Roll gofrontend to 0fde0b6a7eb2

This gives us the sources for cgo, go and gofmt.

llvm-svn: 229174
GitOrigin-RevId: 6393bae4f9089efc8f1be01003ccb714de706106
diff --git a/libgo-noext.diff b/libgo-noext.diff
index 2277270..158e1b9 100644
--- a/libgo-noext.diff
+++ b/libgo-noext.diff
@@ -1,25 +1,25 @@
-diff -r 225a208260a6 libgo/runtime/chan.goc
---- a/libgo/runtime/chan.goc	Mon Sep 22 14:14:24 2014 -0700
-+++ b/libgo/runtime/chan.goc	Tue Sep 23 15:59:57 2014 -0700
-@@ -115,7 +115,7 @@
+diff -r 0fde0b6a7eb2 libgo/runtime/chan.goc
+--- a/libgo/runtime/chan.goc	Fri Jan 09 17:00:26 2015 -0800
++++ b/libgo/runtime/chan.goc	Fri Feb 13 12:12:23 2015 -0800
+@@ -111,7 +111,7 @@
  		mysg.releasetime = -1;
  	}
  
 -	runtime_lock(c);
 +	runtime_lock(&c->lock);
- 	if(raceenabled)
- 		runtime_racereadpc(c, pc, chansend);
  	if(c->closed)
-@@ -128,7 +128,7 @@
+ 		goto closed;
+ 
+@@ -120,7 +120,7 @@
+ 
+ 	sg = dequeue(&c->recvq);
  	if(sg != nil) {
- 		if(raceenabled)
- 			racesync(c, sg);
 -		runtime_unlock(c);
 +		runtime_unlock(&c->lock);
  
  		gp = sg->g;
  		gp->param = sg;
-@@ -141,7 +141,7 @@
+@@ -133,7 +133,7 @@
  	}
  
  	if(!block) {
@@ -28,7 +28,7 @@
  		return false;
  	}
  
-@@ -150,10 +150,10 @@
+@@ -142,10 +142,10 @@
  	mysg.selectdone = nil;
  	g->param = nil;
  	enqueue(&c->sendq, &mysg);
@@ -41,7 +41,7 @@
  		if(!c->closed)
  			runtime_throw("chansend: spurious wakeup");
  		goto closed;
-@@ -170,16 +170,16 @@
+@@ -162,16 +162,16 @@
  
  	if(c->qcount >= c->dataqsiz) {
  		if(!block) {
@@ -61,7 +61,7 @@
  		goto asynch;
  	}
  
-@@ -196,18 +196,18 @@
+@@ -183,18 +183,18 @@
  	sg = dequeue(&c->recvq);
  	if(sg != nil) {
  		gp = sg->g;
@@ -83,7 +83,7 @@
  	runtime_panicstring("send on closed channel");
  	return false;  // not reached
  }
-@@ -247,7 +247,7 @@
+@@ -232,7 +232,7 @@
  		mysg.releasetime = -1;
  	}
  
@@ -92,16 +92,16 @@
  	if(c->dataqsiz > 0)
  		goto asynch;
  
-@@ -258,7 +258,7 @@
+@@ -241,7 +241,7 @@
+ 
+ 	sg = dequeue(&c->sendq);
  	if(sg != nil) {
- 		if(raceenabled)
- 			racesync(c, sg);
 -		runtime_unlock(c);
 +		runtime_unlock(&c->lock);
  
  		if(ep != nil)
  			runtime_memmove(ep, sg->elem, c->elemsize);
-@@ -274,7 +274,7 @@
+@@ -257,7 +257,7 @@
  	}
  
  	if(!block) {
@@ -110,7 +110,7 @@
  		return false;
  	}
  
-@@ -283,10 +283,10 @@
+@@ -266,10 +266,10 @@
  	mysg.selectdone = nil;
  	g->param = nil;
  	enqueue(&c->recvq, &mysg);
@@ -123,7 +123,7 @@
  		if(!c->closed)
  			runtime_throw("chanrecv: spurious wakeup");
  		goto closed;
-@@ -304,7 +304,7 @@
+@@ -287,7 +287,7 @@
  			goto closed;
  
  		if(!block) {
@@ -132,7 +132,7 @@
  			if(received != nil)
  				*received = false;
  			return false;
-@@ -313,9 +313,9 @@
+@@ -296,9 +296,9 @@
  		mysg.elem = nil;
  		mysg.selectdone = nil;
  		enqueue(&c->recvq, &mysg);
@@ -144,7 +144,7 @@
  		goto asynch;
  	}
  
-@@ -334,12 +334,12 @@
+@@ -312,12 +312,12 @@
  	sg = dequeue(&c->sendq);
  	if(sg != nil) {
  		gp = sg->g;
@@ -159,16 +159,16 @@
  
  	if(received != nil)
  		*received = true;
-@@ -354,7 +354,7 @@
+@@ -330,7 +330,7 @@
+ 		runtime_memclr(ep, c->elemsize);
+ 	if(received != nil)
  		*received = false;
- 	if(raceenabled)
- 		runtime_raceacquire(c);
 -	runtime_unlock(c);
 +	runtime_unlock(&c->lock);
  	if(mysg.releasetime > 0)
  		runtime_blockevent(mysg.releasetime - t0, 2);
  	return true;
-@@ -628,7 +628,7 @@
+@@ -604,7 +604,7 @@
  		c0 = sel->lockorder[i];
  		if(c0 && c0 != c) {
  			c = sel->lockorder[i];
@@ -177,7 +177,7 @@
  		}
  	}
  }
-@@ -656,7 +656,7 @@
+@@ -632,7 +632,7 @@
  		c = sel->lockorder[i];
  		if(i>0 && sel->lockorder[i-1] == c)
  			continue;  // will unlock it on the next iteration
@@ -186,7 +186,7 @@
  	}
  }
  
-@@ -1071,9 +1071,9 @@
+@@ -1017,9 +1017,9 @@
  	if(runtime_gcwaiting())
  		runtime_gosched();
  
@@ -197,8 +197,8 @@
 +		runtime_unlock(&c->lock);
  		runtime_panicstring("close of closed channel");
  	}
- 
-@@ -1108,7 +1108,7 @@
+ 	c->closed = true;
+@@ -1048,7 +1048,7 @@
  		runtime_ready(gp);
  	}
  
@@ -207,9 +207,9 @@
  }
  
  void
-diff -r 225a208260a6 libgo/runtime/chan.h
---- a/libgo/runtime/chan.h	Mon Sep 22 14:14:24 2014 -0700
-+++ b/libgo/runtime/chan.h	Tue Sep 23 15:59:57 2014 -0700
+diff -r 0fde0b6a7eb2 libgo/runtime/chan.h
+--- a/libgo/runtime/chan.h	Fri Jan 09 17:00:26 2015 -0800
++++ b/libgo/runtime/chan.h	Fri Feb 13 12:12:23 2015 -0800
 @@ -39,7 +39,7 @@
  	uintgo	recvx;			// receive index
  	WaitQ	recvq;			// list of recv waiters
@@ -219,9 +219,9 @@
  };
  
  // Buffer follows Hchan immediately in memory.
-diff -r 225a208260a6 libgo/runtime/heapdump.c
---- a/libgo/runtime/heapdump.c	Mon Sep 22 14:14:24 2014 -0700
-+++ b/libgo/runtime/heapdump.c	Tue Sep 23 15:59:57 2014 -0700
+diff -r 0fde0b6a7eb2 libgo/runtime/heapdump.c
+--- a/libgo/runtime/heapdump.c	Fri Jan 09 17:00:26 2015 -0800
++++ b/libgo/runtime/heapdump.c	Fri Feb 13 12:12:23 2015 -0800
 @@ -387,7 +387,7 @@
  				if(sp->kind != KindSpecialFinalizer)
  					continue;
@@ -240,10 +240,10 @@
  			dumpint(TagAllocSample);
  			dumpint((uintptr)p);
  			dumpint((uintptr)spp->b);
-diff -r 225a208260a6 libgo/runtime/malloc.goc
---- a/libgo/runtime/malloc.goc	Mon Sep 22 14:14:24 2014 -0700
-+++ b/libgo/runtime/malloc.goc	Tue Sep 23 15:59:57 2014 -0700
-@@ -440,9 +440,9 @@
+diff -r 0fde0b6a7eb2 libgo/runtime/malloc.goc
+--- a/libgo/runtime/malloc.goc	Fri Jan 09 17:00:26 2015 -0800
++++ b/libgo/runtime/malloc.goc	Fri Feb 13 12:12:23 2015 -0800
+@@ -436,9 +436,9 @@
  	m->mcache->local_nlookup++;
  	if (sizeof(void*) == 4 && m->mcache->local_nlookup >= (1<<30)) {
  		// purge cache stats to prevent overflow
@@ -255,7 +255,7 @@
  	}
  
  	s = runtime_MHeap_LookupMaybe(&runtime_mheap, v);
-@@ -743,7 +743,7 @@
+@@ -735,7 +735,7 @@
  
  static struct
  {
@@ -264,7 +264,7 @@
  	byte*	pos;
  	byte*	end;
  } persistent;
-@@ -772,19 +772,19 @@
+@@ -764,19 +764,19 @@
  		align = 8;
  	if(size >= PersistentAllocMaxBlock)
  		return runtime_SysAlloc(size, stat);
@@ -287,9 +287,9 @@
  	if(stat != &mstats.other_sys) {
  		// reaccount the allocation against provided stat
  		runtime_xadd64(stat, size);
-diff -r 225a208260a6 libgo/runtime/malloc.h
---- a/libgo/runtime/malloc.h	Mon Sep 22 14:14:24 2014 -0700
-+++ b/libgo/runtime/malloc.h	Tue Sep 23 15:59:57 2014 -0700
+diff -r 0fde0b6a7eb2 libgo/runtime/malloc.h
+--- a/libgo/runtime/malloc.h	Fri Jan 09 17:00:26 2015 -0800
++++ b/libgo/runtime/malloc.h	Fri Feb 13 12:12:23 2015 -0800
 @@ -390,7 +390,7 @@
  typedef struct SpecialFinalizer SpecialFinalizer;
  struct SpecialFinalizer
@@ -335,9 +335,9 @@
  		byte pad[64];
  	} central[NumSizeClasses];
  
-diff -r 225a208260a6 libgo/runtime/mcache.c
---- a/libgo/runtime/mcache.c	Mon Sep 22 14:14:24 2014 -0700
-+++ b/libgo/runtime/mcache.c	Tue Sep 23 15:59:57 2014 -0700
+diff -r 0fde0b6a7eb2 libgo/runtime/mcache.c
+--- a/libgo/runtime/mcache.c	Fri Jan 09 17:00:26 2015 -0800
++++ b/libgo/runtime/mcache.c	Fri Feb 13 12:12:23 2015 -0800
 @@ -23,9 +23,9 @@
  	MCache *c;
  	int32 i;
@@ -410,9 +410,9 @@
  			l->list = nil;
  			l->nlist = 0;
  		}
-diff -r 225a208260a6 libgo/runtime/mcentral.c
---- a/libgo/runtime/mcentral.c	Mon Sep 22 14:14:24 2014 -0700
-+++ b/libgo/runtime/mcentral.c	Tue Sep 23 15:59:57 2014 -0700
+diff -r 0fde0b6a7eb2 libgo/runtime/mcentral.c
+--- a/libgo/runtime/mcentral.c	Fri Jan 09 17:00:26 2015 -0800
++++ b/libgo/runtime/mcentral.c	Fri Feb 13 12:12:23 2015 -0800
 @@ -39,14 +39,14 @@
  	int32 cap, n;
  	uint32 sg;
@@ -554,10 +554,10 @@
  	runtime_unmarkspan((byte*)(s->start<<PageShift), s->npages<<PageShift);
  	runtime_MHeap_Free(&runtime_mheap, s, 0);
  }
-diff -r 225a208260a6 libgo/runtime/mgc0.c
---- a/libgo/runtime/mgc0.c	Mon Sep 22 14:14:24 2014 -0700
-+++ b/libgo/runtime/mgc0.c	Tue Sep 23 15:59:57 2014 -0700
-@@ -225,7 +225,7 @@
+diff -r 0fde0b6a7eb2 libgo/runtime/mgc0.c
+--- a/libgo/runtime/mgc0.c	Fri Jan 09 17:00:26 2015 -0800
++++ b/libgo/runtime/mgc0.c	Fri Feb 13 12:12:23 2015 -0800
+@@ -224,7 +224,7 @@
  	Note	alldone;
  	ParFor	*markfor;
  
@@ -566,7 +566,7 @@
  	byte	*chunk;
  	uintptr	nchunk;
  } work __attribute__((aligned(8)));
-@@ -1337,7 +1337,7 @@
+@@ -1336,7 +1336,7 @@
  				// retain everything it points to.
  				spf = (SpecialFinalizer*)sp;
  				// A finalizer can be set for an inner byte of an object, find object beginning.
@@ -575,7 +575,7 @@
  				enqueue1(&wbuf, (Obj){p, s->elemsize, 0});
  				enqueue1(&wbuf, (Obj){(void*)&spf->fn, PtrSize, 0});
  				enqueue1(&wbuf, (Obj){(void*)&spf->ft, PtrSize, 0});
-@@ -1378,7 +1378,7 @@
+@@ -1377,7 +1377,7 @@
  	b = (Workbuf*)runtime_lfstackpop(&work.empty);
  	if(b == nil) {
  		// Need to allocate.
@@ -584,7 +584,7 @@
  		if(work.nchunk < sizeof *b) {
  			work.nchunk = 1<<20;
  			work.chunk = runtime_SysAlloc(work.nchunk, &mstats.gc_sys);
-@@ -1388,7 +1388,7 @@
+@@ -1387,7 +1387,7 @@
  		b = (Workbuf*)work.chunk;
  		work.chunk += sizeof *b;
  		work.nchunk -= sizeof *b;
@@ -593,7 +593,7 @@
  	}
  	b->nobj = 0;
  	return b;
-@@ -1802,7 +1802,7 @@
+@@ -1801,7 +1801,7 @@
  		c->local_nsmallfree[cl] += nfree;
  		c->local_cachealloc -= nfree * size;
  		runtime_xadd64(&mstats.next_gc, -(uint64)(nfree * size * (gcpercent + 100)/100));
@@ -602,7 +602,7 @@
  		//MCentral_FreeSpan updates sweepgen
  	}
  	return res;
-@@ -2147,10 +2147,10 @@
+@@ -2146,10 +2146,10 @@
  		return;
  
  	if(gcpercent == GcpercentUnknown) {	// first time through
@@ -615,7 +615,7 @@
  	}
  	if(gcpercent < 0)
  		return;
-@@ -2421,7 +2421,7 @@
+@@ -2420,7 +2420,7 @@
  
  	// Pass back: pauses, last gc (absolute time), number of gc, total pause ns.
  	p = (uint64*)pauses->array;
@@ -624,7 +624,7 @@
  	n = mstats.numgc;
  	if(n > nelem(mstats.pause_ns))
  		n = nelem(mstats.pause_ns);
-@@ -2436,7 +2436,7 @@
+@@ -2435,7 +2435,7 @@
  	p[n] = mstats.last_gc;
  	p[n+1] = mstats.numgc;
  	p[n+2] = mstats.pause_total_ns;	
@@ -633,7 +633,7 @@
  	pauses->__count = n+3;
  }
  
-@@ -2444,14 +2444,14 @@
+@@ -2443,14 +2443,14 @@
  runtime_setgcpercent(int32 in) {
  	int32 out;
  
@@ -650,9 +650,9 @@
  	return out;
  }
  
-diff -r 225a208260a6 libgo/runtime/mheap.c
---- a/libgo/runtime/mheap.c	Mon Sep 22 14:14:24 2014 -0700
-+++ b/libgo/runtime/mheap.c	Tue Sep 23 15:59:57 2014 -0700
+diff -r 0fde0b6a7eb2 libgo/runtime/mheap.c
+--- a/libgo/runtime/mheap.c	Fri Jan 09 17:00:26 2015 -0800
++++ b/libgo/runtime/mheap.c	Fri Feb 13 12:12:23 2015 -0800
 @@ -70,7 +70,7 @@
  	runtime_MSpanList_Init(&h->freelarge);
  	runtime_MSpanList_Init(&h->busylarge);
@@ -837,9 +837,9 @@
 +		runtime_unlock(&h->lock);
  	}
  }
-diff -r 225a208260a6 libgo/runtime/netpoll.goc
---- a/libgo/runtime/netpoll.goc	Mon Sep 22 14:14:24 2014 -0700
-+++ b/libgo/runtime/netpoll.goc	Tue Sep 23 15:59:57 2014 -0700
+diff -r 0fde0b6a7eb2 libgo/runtime/netpoll.goc
+--- a/libgo/runtime/netpoll.goc	Fri Jan 09 17:00:26 2015 -0800
++++ b/libgo/runtime/netpoll.goc	Fri Feb 13 12:12:23 2015 -0800
 @@ -53,7 +53,7 @@
  	// pollReset, pollWait, pollWaitCanceled and runtime_netpollready (IO rediness notification)
  	// proceed w/o taking the lock. So closing, rg, rd, wg and wd are manipulated
@@ -983,10 +983,10 @@
 +	runtime_unlock(&pollcache.lock);
  	return pd;
  }
-diff -r 225a208260a6 libgo/runtime/proc.c
---- a/libgo/runtime/proc.c	Mon Sep 22 14:14:24 2014 -0700
-+++ b/libgo/runtime/proc.c	Tue Sep 23 15:59:57 2014 -0700
-@@ -357,7 +357,7 @@
+diff -r 0fde0b6a7eb2 libgo/runtime/proc.c
+--- a/libgo/runtime/proc.c	Fri Jan 09 17:00:26 2015 -0800
++++ b/libgo/runtime/proc.c	Fri Feb 13 12:12:23 2015 -0800
+@@ -302,7 +302,7 @@
  
  typedef struct Sched Sched;
  struct Sched {
@@ -995,7 +995,7 @@
  
  	uint64	goidgen;
  	M*	midle;	 // idle m's waiting for work
-@@ -770,7 +770,7 @@
+@@ -709,7 +709,7 @@
  
  	mp->fastrand = 0x49f6428aUL + mp->id + runtime_cputicks();
  
@@ -1004,7 +1004,7 @@
  	mp->id = runtime_sched.mcount++;
  	checkmcount();
  	runtime_mpreinit(mp);
-@@ -781,7 +781,7 @@
+@@ -720,7 +720,7 @@
  	// runtime_NumCgoCall() iterates over allm w/o schedlock,
  	// so we need to publish it safely.
  	runtime_atomicstorep(&runtime_allm, mp);
@@ -1013,7 +1013,7 @@
  }
  
  // Mark gp ready to run.
-@@ -808,7 +808,7 @@
+@@ -747,7 +747,7 @@
  
  	// Figure out how many CPUs to use during GC.
  	// Limited by gomaxprocs, number of actual CPUs, and MaxGcproc.
@@ -1022,7 +1022,7 @@
  	n = runtime_gomaxprocs;
  	if(n > runtime_ncpu)
  		n = runtime_ncpu > 0 ? runtime_ncpu : 1;
-@@ -816,7 +816,7 @@
+@@ -755,7 +755,7 @@
  		n = MaxGcproc;
  	if(n > runtime_sched.nmidle+1) // one M is currently running
  		n = runtime_sched.nmidle+1;
@@ -1031,7 +1031,7 @@
  	return n;
  }
  
-@@ -825,14 +825,14 @@
+@@ -764,14 +764,14 @@
  {
  	int32 n;
  
@@ -1048,7 +1048,7 @@
  	return n > 0;
  }
  
-@@ -842,7 +842,7 @@
+@@ -781,7 +781,7 @@
  	M *mp;
  	int32 n, pos;
  
@@ -1057,7 +1057,7 @@
  	pos = 0;
  	for(n = 1; n < nproc; n++) {  // one M is currently running
  		if(runtime_allp[pos]->mcache == m->mcache)
-@@ -855,7 +855,7 @@
+@@ -794,7 +794,7 @@
  		pos++;
  		runtime_notewakeup(&mp->park);
  	}
@@ -1066,7 +1066,7 @@
  }
  
  // Similar to stoptheworld but best-effort and can be called several times.
-@@ -894,7 +894,7 @@
+@@ -833,7 +833,7 @@
  	P *p;
  	bool wait;
  
@@ -1075,7 +1075,7 @@
  	runtime_sched.stopwait = runtime_gomaxprocs;
  	runtime_atomicstore((uint32*)&runtime_sched.gcwaiting, 1);
  	preemptall();
-@@ -914,7 +914,7 @@
+@@ -853,7 +853,7 @@
  		runtime_sched.stopwait--;
  	}
  	wait = runtime_sched.stopwait > 0;
@@ -1084,7 +1084,7 @@
  
  	// wait for remaining P's to stop voluntarily
  	if(wait) {
-@@ -948,7 +948,7 @@
+@@ -887,7 +887,7 @@
  	gp = runtime_netpoll(false);  // non-blocking
  	injectglist(gp);
  	add = needaddgcproc();
@@ -1093,7 +1093,7 @@
  	if(newprocs) {
  		procresize(newprocs);
  		newprocs = 0;
-@@ -972,7 +972,7 @@
+@@ -911,7 +911,7 @@
  		runtime_sched.sysmonwait = false;
  		runtime_notewakeup(&runtime_sched.sysmonnote);
  	}
@@ -1102,7 +1102,7 @@
  
  	while(p1) {
  		p = p1;
-@@ -1404,9 +1404,9 @@
+@@ -1346,9 +1346,9 @@
  	}
  
  retry:
@@ -1114,7 +1114,7 @@
  	runtime_notesleep(&m->park);
  	runtime_noteclear(&m->park);
  	if(m->helpgc) {
-@@ -1433,18 +1433,18 @@
+@@ -1375,18 +1375,18 @@
  	M *mp;
  	void (*fn)(void);
  
@@ -1136,7 +1136,7 @@
  	if(mp == nil) {
  		fn = nil;
  		if(spinning)
-@@ -1477,28 +1477,28 @@
+@@ -1419,28 +1419,28 @@
  		startm(p, true);
  		return;
  	}
@@ -1170,7 +1170,7 @@
  }
  
  // Tries to add one more P to execute G's.
-@@ -1570,11 +1570,11 @@
+@@ -1512,11 +1512,11 @@
  		runtime_xadd(&runtime_sched.nmspinning, -1);
  	}
  	p = releasep();
@@ -1184,7 +1184,7 @@
  	stopm();
  }
  
-@@ -1625,9 +1625,9 @@
+@@ -1567,9 +1567,9 @@
  		return gp;
  	// global runq
  	if(runtime_sched.runqsize) {
@@ -1196,7 +1196,7 @@
  		if(gp)
  			return gp;
  	}
-@@ -1661,19 +1661,19 @@
+@@ -1603,19 +1603,19 @@
  	}
  stop:
  	// return P and block
@@ -1220,7 +1220,7 @@
  	if(m->spinning) {
  		m->spinning = false;
  		runtime_xadd(&runtime_sched.nmspinning, -1);
-@@ -1682,9 +1682,9 @@
+@@ -1624,9 +1624,9 @@
  	for(i = 0; i < runtime_gomaxprocs; i++) {
  		p = runtime_allp[i];
  		if(p && p->runqhead != p->runqtail) {
@@ -1232,7 +1232,7 @@
  			if(p) {
  				acquirep(p);
  				goto top;
-@@ -1701,9 +1701,9 @@
+@@ -1643,9 +1643,9 @@
  		gp = runtime_netpoll(true);  // block until new work is available
  		runtime_atomicstore64(&runtime_sched.lastpoll, runtime_nanotime());
  		if(gp) {
@@ -1244,7 +1244,7 @@
  			if(p) {
  				acquirep(p);
  				injectglist(gp->schedlink);
-@@ -1746,14 +1746,14 @@
+@@ -1688,14 +1688,14 @@
  
  	if(glist == nil)
  		return;
@@ -1261,7 +1261,7 @@
  
  	for(; n && runtime_sched.npidle; n--)
  		startm(nil, false);
-@@ -1784,9 +1784,9 @@
+@@ -1726,9 +1726,9 @@
  	// This is a fancy way to say tick%61==0,
  	// it uses 2 MUL instructions instead of a single DIV and so is faster on modern processors.
  	if(tick - (((uint64)tick*0x4325c53fu)>>36)*61 == 0 && runtime_sched.runqsize > 0) {
@@ -1273,7 +1273,7 @@
  		if(gp)
  			resetspinning();
  	}
-@@ -1880,9 +1880,9 @@
+@@ -1822,9 +1822,9 @@
  	gp->status = Grunnable;
  	gp->m = nil;
  	m->curg = nil;
@@ -1285,7 +1285,7 @@
  	if(m->lockedg) {
  		stoplockedm();
  		execute(gp);  // Never returns.
-@@ -1985,24 +1985,24 @@
+@@ -1925,24 +1925,24 @@
  	g->status = Gsyscall;
  
  	if(runtime_atomicload(&runtime_sched.sysmonwait)) {  // TODO: fast atomic
@@ -1314,7 +1314,7 @@
  	}
  
  	m->locks--;
-@@ -2113,13 +2113,13 @@
+@@ -2053,13 +2053,13 @@
  	// Try to get any other idle P.
  	m->p = nil;
  	if(runtime_sched.pidle) {
@@ -1330,7 +1330,7 @@
  		if(p) {
  			acquirep(p);
  			return true;
-@@ -2138,7 +2138,7 @@
+@@ -2078,7 +2078,7 @@
  	gp->status = Grunnable;
  	gp->m = nil;
  	m->curg = nil;
@@ -1339,7 +1339,7 @@
  	p = pidleget();
  	if(p == nil)
  		globrunqput(gp);
-@@ -2146,7 +2146,7 @@
+@@ -2086,7 +2086,7 @@
  		runtime_atomicstore(&runtime_sched.sysmonwait, 0);
  		runtime_notewakeup(&runtime_sched.sysmonnote);
  	}
@@ -1348,7 +1348,7 @@
  	if(p) {
  		acquirep(p);
  		execute(gp);  // Never returns.
-@@ -2425,13 +2425,13 @@
+@@ -2365,13 +2365,13 @@
  
  	if(n > MaxGomaxprocs)
  		n = MaxGomaxprocs;
@@ -1365,7 +1365,7 @@
  
  	runtime_semacquire(&runtime_worldsema, false);
  	m->gcing = 1;
-@@ -2536,7 +2536,7 @@
+@@ -2476,7 +2476,7 @@
  }
  
  static struct {
@@ -1374,7 +1374,7 @@
  	void (*fn)(uintptr*, int32);
  	int32 hz;
  	uintptr pcbuf[TracebackMaxFrames];
-@@ -2568,9 +2568,9 @@
+@@ -2508,9 +2508,9 @@
  	if(mp->mcache == nil)
  		traceback = false;
  
@@ -1386,7 +1386,7 @@
  		mp->mallocing--;
  		return;
  	}
-@@ -2598,7 +2598,7 @@
+@@ -2538,7 +2538,7 @@
  			prof.pcbuf[1] = (uintptr)System;
  	}
  	prof.fn(prof.pcbuf, n);
@@ -1395,7 +1395,7 @@
  	mp->mallocing--;
  }
  
-@@ -2623,13 +2623,13 @@
+@@ -2563,13 +2563,13 @@
  	// it would deadlock.
  	runtime_resetcpuprofiler(0);
  
@@ -1413,7 +1413,7 @@
  
  	if(hz != 0)
  		runtime_resetcpuprofiler(hz);
-@@ -2767,11 +2767,11 @@
+@@ -2707,11 +2707,11 @@
  static void
  incidlelocked(int32 v)
  {
@@ -1427,7 +1427,7 @@
  }
  
  // Check for deadlock situation.
-@@ -2840,16 +2840,16 @@
+@@ -2780,16 +2780,16 @@
  		runtime_usleep(delay);
  		if(runtime_debug.schedtrace <= 0 &&
  			(runtime_sched.gcwaiting || runtime_atomicload(&runtime_sched.npidle) == (uint32)runtime_gomaxprocs)) {  // TODO: fast atomic
@@ -1447,7 +1447,7 @@
  		}
  		// poll network if not polled for more than 10ms
  		lastpoll = runtime_atomicload64(&runtime_sched.lastpoll);
-@@ -2978,7 +2978,7 @@
+@@ -2918,7 +2918,7 @@
  	if(starttime == 0)
  		starttime = now;
  
@@ -1456,7 +1456,7 @@
  	runtime_printf("SCHED %Dms: gomaxprocs=%d idleprocs=%d threads=%d idlethreads=%d runqueue=%d",
  		(now-starttime)/1000000, runtime_gomaxprocs, runtime_sched.npidle, runtime_sched.mcount,
  		runtime_sched.nmidle, runtime_sched.runqsize);
-@@ -3014,7 +3014,7 @@
+@@ -2954,7 +2954,7 @@
  		}
  	}
  	if(!detailed) {
@@ -1465,7 +1465,7 @@
  		return;
  	}
  	for(mp = runtime_allm; mp; mp = mp->alllink) {
-@@ -3046,7 +3046,7 @@
+@@ -2986,7 +2986,7 @@
  			lockedm ? lockedm->id : -1);
  	}
  	runtime_unlock(&allglock);
@@ -1474,7 +1474,7 @@
  }
  
  // Put mp on midle list.
-@@ -3202,9 +3202,9 @@
+@@ -3142,9 +3142,9 @@
  	for(i=0; i<n; i++)
  		batch[i]->schedlink = batch[i+1];
  	// Now put the batch on global queue.
@@ -1486,7 +1486,7 @@
  	return true;
  }
  
-@@ -3356,11 +3356,11 @@
+@@ -3296,11 +3296,11 @@
  {
  	int32 out;
  
@@ -1500,9 +1500,9 @@
  	return out;
  }
  
-diff -r 225a208260a6 libgo/runtime/runtime.h
---- a/libgo/runtime/runtime.h	Mon Sep 22 14:14:24 2014 -0700
-+++ b/libgo/runtime/runtime.h	Tue Sep 23 15:59:57 2014 -0700
+diff -r 0fde0b6a7eb2 libgo/runtime/runtime.h
+--- a/libgo/runtime/runtime.h	Fri Jan 09 17:00:26 2015 -0800
++++ b/libgo/runtime/runtime.h	Fri Feb 13 12:12:23 2015 -0800
 @@ -286,7 +286,7 @@
  
  struct P
@@ -1521,9 +1521,9 @@
  	G	*timerproc;
  	bool		sleeping;
  	bool		rescheduling;
-diff -r 225a208260a6 libgo/runtime/sema.goc
---- a/libgo/runtime/sema.goc	Mon Sep 22 14:14:24 2014 -0700
-+++ b/libgo/runtime/sema.goc	Tue Sep 23 15:59:57 2014 -0700
+diff -r 0fde0b6a7eb2 libgo/runtime/sema.goc
+--- a/libgo/runtime/sema.goc	Fri Jan 09 17:00:26 2015 -0800
++++ b/libgo/runtime/sema.goc	Fri Feb 13 12:12:23 2015 -0800
 @@ -35,7 +35,7 @@
  typedef struct SemaRoot SemaRoot;
  struct SemaRoot
@@ -1652,9 +1652,9 @@
 -		runtime_unlock(s);
 +		runtime_unlock(&s->lock);
  }
-diff -r 225a208260a6 libgo/runtime/sigqueue.goc
---- a/libgo/runtime/sigqueue.goc	Mon Sep 22 14:14:24 2014 -0700
-+++ b/libgo/runtime/sigqueue.goc	Tue Sep 23 15:59:57 2014 -0700
+diff -r 0fde0b6a7eb2 libgo/runtime/sigqueue.goc
+--- a/libgo/runtime/sigqueue.goc	Fri Jan 09 17:00:26 2015 -0800
++++ b/libgo/runtime/sigqueue.goc	Fri Feb 13 12:12:23 2015 -0800
 @@ -32,7 +32,7 @@
  #include "defs.h"
  
@@ -1693,10 +1693,10 @@
  		return;
  	}
  	
-diff -r 225a208260a6 libgo/runtime/time.goc
---- a/libgo/runtime/time.goc	Mon Sep 22 14:14:24 2014 -0700
-+++ b/libgo/runtime/time.goc	Tue Sep 23 15:59:57 2014 -0700
-@@ -94,17 +94,17 @@
+diff -r 0fde0b6a7eb2 libgo/runtime/time.goc
+--- a/libgo/runtime/time.goc	Fri Jan 09 17:00:26 2015 -0800
++++ b/libgo/runtime/time.goc	Fri Feb 13 12:12:23 2015 -0800
+@@ -91,17 +91,17 @@
  	t.period = 0;
  	t.fv = &readyv;
  	t.arg.__object = g;
@@ -1718,7 +1718,7 @@
  }
  
  // Add a timer to the heap and start or kick the timer proc
-@@ -169,14 +169,14 @@
+@@ -166,14 +166,14 @@
  	i = t->i;
  	gi = i;
  
@@ -1735,7 +1735,7 @@
  		return false;
  	}
  
-@@ -192,7 +192,7 @@
+@@ -189,7 +189,7 @@
  	}
  	if(debug)
  		dumptimers("deltimer");
@@ -1744,7 +1744,7 @@
  	return true;
  }
  
-@@ -210,7 +210,7 @@
+@@ -207,7 +207,7 @@
  	Eface arg;
  
  	for(;;) {
@@ -1753,16 +1753,16 @@
  		timers.sleeping = false;
  		now = runtime_nanotime();
  		for(;;) {
-@@ -236,7 +236,7 @@
+@@ -233,7 +233,7 @@
  			fv = t->fv;
  			f = (void*)t->fv->fn;
  			arg = t->arg;
 -			runtime_unlock(&timers);
 +			runtime_unlock(&timers.lock);
- 			if(raceenabled)
- 				runtime_raceacquire(t);
  			__go_set_closure(fv);
-@@ -249,20 +249,20 @@
+ 			f(now, arg);
+ 
+@@ -244,20 +244,20 @@
  			arg.__object = nil;
  			USED(&arg);
  
diff --git a/third_party/gofrontend/config.sub b/third_party/gofrontend/config.sub
index 673d62b..01956e9 100755
--- a/third_party/gofrontend/config.sub
+++ b/third_party/gofrontend/config.sub
@@ -1489,6 +1489,8 @@
 		;;
 	-nacl*)
 		;;
+	-ps4)
+		;;
 	-none)
 		;;
 	*)
diff --git a/third_party/gofrontend/libgo/Makefile.am b/third_party/gofrontend/libgo/Makefile.am
index 48114d1..526b656 100644
--- a/third_party/gofrontend/libgo/Makefile.am
+++ b/third_party/gofrontend/libgo/Makefile.am
@@ -26,6 +26,7 @@
 toolexecdir = $(glibgo_toolexecdir)
 toolexeclibdir = $(glibgo_toolexeclibdir)
 toolexeclibgodir = $(nover_glibgo_toolexeclibdir)/go/$(gcc_version)/$(target_alias)
+libexecsubdir = $(libexecdir)/gcc/$(target_alias)/$(gcc_version)
 
 LIBFFI = @LIBFFI@
 LIBFFIINCS = @LIBFFIINCS@
@@ -1007,6 +1008,7 @@
 	echo 'const theVersion = "'`$(GOC) --version | sed 1q`'"' >> version.go.tmp
 	echo 'const theGoarch = "'$(GOARCH)'"' >> version.go.tmp
 	echo 'const theGoos = "'$(GOOS)'"' >> version.go.tmp
+	echo 'const theGccgoToolDir = "$(libexecsubdir)"' >> version.go.tmp
 	$(SHELL) $(srcdir)/mvifdiff.sh version.go.tmp version.go
 	$(STAMP) $@
 
@@ -1812,7 +1814,7 @@
 
 sysinfo.go: s-sysinfo; @true
 s-sysinfo: $(srcdir)/mksysinfo.sh config.h
-	CC="$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(OSCFLAGS)" $(SHELL) $(srcdir)/mksysinfo.sh
+	CC="$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(OSCFLAGS) -O" $(SHELL) $(srcdir)/mksysinfo.sh
 	$(SHELL) $(srcdir)/mvifdiff.sh tmp-sysinfo.go sysinfo.go
 	$(STAMP) $@
 
diff --git a/third_party/gofrontend/libgo/Makefile.in b/third_party/gofrontend/libgo/Makefile.in
index 259d134..2254478 100644
--- a/third_party/gofrontend/libgo/Makefile.in
+++ b/third_party/gofrontend/libgo/Makefile.in
@@ -454,6 +454,7 @@
 toolexecdir = $(glibgo_toolexecdir)
 toolexeclibdir = $(glibgo_toolexeclibdir)
 toolexeclibgodir = $(nover_glibgo_toolexeclibdir)/go/$(gcc_version)/$(target_alias)
+libexecsubdir = $(libexecdir)/gcc/$(target_alias)/$(gcc_version)
 WARN_CFLAGS = $(WARN_FLAGS) $(WERROR)
 
 # -I/-D flags to pass when compiling.
@@ -4392,6 +4393,7 @@
 	echo 'const theVersion = "'`$(GOC) --version | sed 1q`'"' >> version.go.tmp
 	echo 'const theGoarch = "'$(GOARCH)'"' >> version.go.tmp
 	echo 'const theGoos = "'$(GOOS)'"' >> version.go.tmp
+	echo 'const theGccgoToolDir = "$(libexecsubdir)"' >> version.go.tmp
 	$(SHELL) $(srcdir)/mvifdiff.sh version.go.tmp version.go
 	$(STAMP) $@
 
@@ -4421,7 +4423,7 @@
 
 sysinfo.go: s-sysinfo; @true
 s-sysinfo: $(srcdir)/mksysinfo.sh config.h
-	CC="$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(OSCFLAGS)" $(SHELL) $(srcdir)/mksysinfo.sh
+	CC="$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(OSCFLAGS) -O" $(SHELL) $(srcdir)/mksysinfo.sh
 	$(SHELL) $(srcdir)/mvifdiff.sh tmp-sysinfo.go sysinfo.go
 	$(STAMP) $@
 
diff --git a/third_party/gofrontend/libgo/go/cmd/cgo/ast.go b/third_party/gofrontend/libgo/go/cmd/cgo/ast.go
new file mode 100644
index 0000000..7757efa
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/cgo/ast.go
@@ -0,0 +1,460 @@
+// 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.
+
+// Parse input AST and prepare Prog structure.
+
+package main
+
+import (
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/scanner"
+	"go/token"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+func parse(name string, flags parser.Mode) *ast.File {
+	ast1, err := parser.ParseFile(fset, name, nil, flags)
+	if err != nil {
+		if list, ok := err.(scanner.ErrorList); ok {
+			// If err is a scanner.ErrorList, its String will print just
+			// the first error and then (+n more errors).
+			// Instead, turn it into a new Error that will return
+			// details for all the errors.
+			for _, e := range list {
+				fmt.Fprintln(os.Stderr, e)
+			}
+			os.Exit(2)
+		}
+		fatalf("parsing %s: %s", name, err)
+	}
+	return ast1
+}
+
+func sourceLine(n ast.Node) int {
+	return fset.Position(n.Pos()).Line
+}
+
+// ReadGo populates f with information learned from reading the
+// Go source file with the given file name.  It gathers the C preamble
+// attached to the import "C" comment, a list of references to C.xxx,
+// a list of exported functions, and the actual AST, to be rewritten and
+// printed.
+func (f *File) ReadGo(name string) {
+	// Create absolute path for file, so that it will be used in error
+	// messages and recorded in debug line number information.
+	// This matches the rest of the toolchain. See golang.org/issue/5122.
+	if aname, err := filepath.Abs(name); err == nil {
+		name = aname
+	}
+
+	// Two different parses: once with comments, once without.
+	// The printer is not good enough at printing comments in the
+	// right place when we start editing the AST behind its back,
+	// so we use ast1 to look for the doc comments on import "C"
+	// and on exported functions, and we use ast2 for translating
+	// and reprinting.
+	ast1 := parse(name, parser.ParseComments)
+	ast2 := parse(name, 0)
+
+	f.Package = ast1.Name.Name
+	f.Name = make(map[string]*Name)
+
+	// In ast1, find the import "C" line and get any extra C preamble.
+	sawC := false
+	for _, decl := range ast1.Decls {
+		d, ok := decl.(*ast.GenDecl)
+		if !ok {
+			continue
+		}
+		for _, spec := range d.Specs {
+			s, ok := spec.(*ast.ImportSpec)
+			if !ok || string(s.Path.Value) != `"C"` {
+				continue
+			}
+			sawC = true
+			if s.Name != nil {
+				error_(s.Path.Pos(), `cannot rename import "C"`)
+			}
+			cg := s.Doc
+			if cg == nil && len(d.Specs) == 1 {
+				cg = d.Doc
+			}
+			if cg != nil {
+				f.Preamble += fmt.Sprintf("#line %d %q\n", sourceLine(cg), name)
+				f.Preamble += commentText(cg) + "\n"
+			}
+		}
+	}
+	if !sawC {
+		error_(token.NoPos, `cannot find import "C"`)
+	}
+
+	// In ast2, strip the import "C" line.
+	w := 0
+	for _, decl := range ast2.Decls {
+		d, ok := decl.(*ast.GenDecl)
+		if !ok {
+			ast2.Decls[w] = decl
+			w++
+			continue
+		}
+		ws := 0
+		for _, spec := range d.Specs {
+			s, ok := spec.(*ast.ImportSpec)
+			if !ok || string(s.Path.Value) != `"C"` {
+				d.Specs[ws] = spec
+				ws++
+			}
+		}
+		if ws == 0 {
+			continue
+		}
+		d.Specs = d.Specs[0:ws]
+		ast2.Decls[w] = d
+		w++
+	}
+	ast2.Decls = ast2.Decls[0:w]
+
+	// Accumulate pointers to uses of C.x.
+	if f.Ref == nil {
+		f.Ref = make([]*Ref, 0, 8)
+	}
+	f.walk(ast2, "prog", (*File).saveRef)
+
+	// Accumulate exported functions.
+	// The comments are only on ast1 but we need to
+	// save the function bodies from ast2.
+	// The first walk fills in ExpFunc, and the
+	// second walk changes the entries to
+	// refer to ast2 instead.
+	f.walk(ast1, "prog", (*File).saveExport)
+	f.walk(ast2, "prog", (*File).saveExport2)
+
+	f.Comments = ast1.Comments
+	f.AST = ast2
+}
+
+// Like ast.CommentGroup's Text method but preserves
+// leading blank lines, so that line numbers line up.
+func commentText(g *ast.CommentGroup) string {
+	if g == nil {
+		return ""
+	}
+	var pieces []string
+	for _, com := range g.List {
+		c := string(com.Text)
+		// Remove comment markers.
+		// The parser has given us exactly the comment text.
+		switch c[1] {
+		case '/':
+			//-style comment (no newline at the end)
+			c = c[2:] + "\n"
+		case '*':
+			/*-style comment */
+			c = c[2 : len(c)-2]
+		}
+		pieces = append(pieces, c)
+	}
+	return strings.Join(pieces, "")
+}
+
+// Save references to C.xxx for later processing.
+func (f *File) saveRef(x interface{}, context string) {
+	n, ok := x.(*ast.Expr)
+	if !ok {
+		return
+	}
+	if sel, ok := (*n).(*ast.SelectorExpr); ok {
+		// For now, assume that the only instance of capital C is
+		// when used as the imported package identifier.
+		// The parser should take care of scoping in the future,
+		// so that we will be able to distinguish a "top-level C"
+		// from a local C.
+		if l, ok := sel.X.(*ast.Ident); ok && l.Name == "C" {
+			if context == "as2" {
+				context = "expr"
+			}
+			if context == "embed-type" {
+				error_(sel.Pos(), "cannot embed C type")
+			}
+			goname := sel.Sel.Name
+			if goname == "errno" {
+				error_(sel.Pos(), "cannot refer to errno directly; see documentation")
+				return
+			}
+			if goname == "_CMalloc" {
+				error_(sel.Pos(), "cannot refer to C._CMalloc; use C.malloc")
+				return
+			}
+			if goname == "malloc" {
+				goname = "_CMalloc"
+			}
+			name := f.Name[goname]
+			if name == nil {
+				name = &Name{
+					Go: goname,
+				}
+				f.Name[goname] = name
+			}
+			f.Ref = append(f.Ref, &Ref{
+				Name:    name,
+				Expr:    n,
+				Context: context,
+			})
+			return
+		}
+	}
+}
+
+// If a function should be exported add it to ExpFunc.
+func (f *File) saveExport(x interface{}, context string) {
+	n, ok := x.(*ast.FuncDecl)
+	if !ok {
+		return
+	}
+
+	if n.Doc == nil {
+		return
+	}
+	for _, c := range n.Doc.List {
+		if !strings.HasPrefix(string(c.Text), "//export ") {
+			continue
+		}
+
+		name := strings.TrimSpace(string(c.Text[9:]))
+		if name == "" {
+			error_(c.Pos(), "export missing name")
+		}
+
+		if name != n.Name.Name {
+			error_(c.Pos(), "export comment has wrong name %q, want %q", name, n.Name.Name)
+		}
+
+		f.ExpFunc = append(f.ExpFunc, &ExpFunc{
+			Func:    n,
+			ExpName: name,
+		})
+		break
+	}
+}
+
+// Make f.ExpFunc[i] point at the Func from this AST instead of the other one.
+func (f *File) saveExport2(x interface{}, context string) {
+	n, ok := x.(*ast.FuncDecl)
+	if !ok {
+		return
+	}
+
+	for _, exp := range f.ExpFunc {
+		if exp.Func.Name.Name == n.Name.Name {
+			exp.Func = n
+			break
+		}
+	}
+}
+
+// walk walks the AST x, calling visit(f, x, context) for each node.
+func (f *File) walk(x interface{}, context string, visit func(*File, interface{}, string)) {
+	visit(f, x, context)
+	switch n := x.(type) {
+	case *ast.Expr:
+		f.walk(*n, context, visit)
+
+	// everything else just recurs
+	default:
+		error_(token.NoPos, "unexpected type %T in walk", x, visit)
+		panic("unexpected type")
+
+	case nil:
+
+	// These are ordered and grouped to match ../../pkg/go/ast/ast.go
+	case *ast.Field:
+		if len(n.Names) == 0 && context == "field" {
+			f.walk(&n.Type, "embed-type", visit)
+		} else {
+			f.walk(&n.Type, "type", visit)
+		}
+	case *ast.FieldList:
+		for _, field := range n.List {
+			f.walk(field, context, visit)
+		}
+	case *ast.BadExpr:
+	case *ast.Ident:
+	case *ast.Ellipsis:
+	case *ast.BasicLit:
+	case *ast.FuncLit:
+		f.walk(n.Type, "type", visit)
+		f.walk(n.Body, "stmt", visit)
+	case *ast.CompositeLit:
+		f.walk(&n.Type, "type", visit)
+		f.walk(n.Elts, "expr", visit)
+	case *ast.ParenExpr:
+		f.walk(&n.X, context, visit)
+	case *ast.SelectorExpr:
+		f.walk(&n.X, "selector", visit)
+	case *ast.IndexExpr:
+		f.walk(&n.X, "expr", visit)
+		f.walk(&n.Index, "expr", visit)
+	case *ast.SliceExpr:
+		f.walk(&n.X, "expr", visit)
+		if n.Low != nil {
+			f.walk(&n.Low, "expr", visit)
+		}
+		if n.High != nil {
+			f.walk(&n.High, "expr", visit)
+		}
+	case *ast.TypeAssertExpr:
+		f.walk(&n.X, "expr", visit)
+		f.walk(&n.Type, "type", visit)
+	case *ast.CallExpr:
+		if context == "as2" {
+			f.walk(&n.Fun, "call2", visit)
+		} else {
+			f.walk(&n.Fun, "call", visit)
+		}
+		f.walk(n.Args, "expr", visit)
+	case *ast.StarExpr:
+		f.walk(&n.X, context, visit)
+	case *ast.UnaryExpr:
+		f.walk(&n.X, "expr", visit)
+	case *ast.BinaryExpr:
+		f.walk(&n.X, "expr", visit)
+		f.walk(&n.Y, "expr", visit)
+	case *ast.KeyValueExpr:
+		f.walk(&n.Key, "expr", visit)
+		f.walk(&n.Value, "expr", visit)
+
+	case *ast.ArrayType:
+		f.walk(&n.Len, "expr", visit)
+		f.walk(&n.Elt, "type", visit)
+	case *ast.StructType:
+		f.walk(n.Fields, "field", visit)
+	case *ast.FuncType:
+		f.walk(n.Params, "param", visit)
+		if n.Results != nil {
+			f.walk(n.Results, "param", visit)
+		}
+	case *ast.InterfaceType:
+		f.walk(n.Methods, "field", visit)
+	case *ast.MapType:
+		f.walk(&n.Key, "type", visit)
+		f.walk(&n.Value, "type", visit)
+	case *ast.ChanType:
+		f.walk(&n.Value, "type", visit)
+
+	case *ast.BadStmt:
+	case *ast.DeclStmt:
+		f.walk(n.Decl, "decl", visit)
+	case *ast.EmptyStmt:
+	case *ast.LabeledStmt:
+		f.walk(n.Stmt, "stmt", visit)
+	case *ast.ExprStmt:
+		f.walk(&n.X, "expr", visit)
+	case *ast.SendStmt:
+		f.walk(&n.Chan, "expr", visit)
+		f.walk(&n.Value, "expr", visit)
+	case *ast.IncDecStmt:
+		f.walk(&n.X, "expr", visit)
+	case *ast.AssignStmt:
+		f.walk(n.Lhs, "expr", visit)
+		if len(n.Lhs) == 2 && len(n.Rhs) == 1 {
+			f.walk(n.Rhs, "as2", visit)
+		} else {
+			f.walk(n.Rhs, "expr", visit)
+		}
+	case *ast.GoStmt:
+		f.walk(n.Call, "expr", visit)
+	case *ast.DeferStmt:
+		f.walk(n.Call, "expr", visit)
+	case *ast.ReturnStmt:
+		f.walk(n.Results, "expr", visit)
+	case *ast.BranchStmt:
+	case *ast.BlockStmt:
+		f.walk(n.List, context, visit)
+	case *ast.IfStmt:
+		f.walk(n.Init, "stmt", visit)
+		f.walk(&n.Cond, "expr", visit)
+		f.walk(n.Body, "stmt", visit)
+		f.walk(n.Else, "stmt", visit)
+	case *ast.CaseClause:
+		if context == "typeswitch" {
+			context = "type"
+		} else {
+			context = "expr"
+		}
+		f.walk(n.List, context, visit)
+		f.walk(n.Body, "stmt", visit)
+	case *ast.SwitchStmt:
+		f.walk(n.Init, "stmt", visit)
+		f.walk(&n.Tag, "expr", visit)
+		f.walk(n.Body, "switch", visit)
+	case *ast.TypeSwitchStmt:
+		f.walk(n.Init, "stmt", visit)
+		f.walk(n.Assign, "stmt", visit)
+		f.walk(n.Body, "typeswitch", visit)
+	case *ast.CommClause:
+		f.walk(n.Comm, "stmt", visit)
+		f.walk(n.Body, "stmt", visit)
+	case *ast.SelectStmt:
+		f.walk(n.Body, "stmt", visit)
+	case *ast.ForStmt:
+		f.walk(n.Init, "stmt", visit)
+		f.walk(&n.Cond, "expr", visit)
+		f.walk(n.Post, "stmt", visit)
+		f.walk(n.Body, "stmt", visit)
+	case *ast.RangeStmt:
+		f.walk(&n.Key, "expr", visit)
+		f.walk(&n.Value, "expr", visit)
+		f.walk(&n.X, "expr", visit)
+		f.walk(n.Body, "stmt", visit)
+
+	case *ast.ImportSpec:
+	case *ast.ValueSpec:
+		f.walk(&n.Type, "type", visit)
+		f.walk(n.Values, "expr", visit)
+	case *ast.TypeSpec:
+		f.walk(&n.Type, "type", visit)
+
+	case *ast.BadDecl:
+	case *ast.GenDecl:
+		f.walk(n.Specs, "spec", visit)
+	case *ast.FuncDecl:
+		if n.Recv != nil {
+			f.walk(n.Recv, "param", visit)
+		}
+		f.walk(n.Type, "type", visit)
+		if n.Body != nil {
+			f.walk(n.Body, "stmt", visit)
+		}
+
+	case *ast.File:
+		f.walk(n.Decls, "decl", visit)
+
+	case *ast.Package:
+		for _, file := range n.Files {
+			f.walk(file, "file", visit)
+		}
+
+	case []ast.Decl:
+		for _, d := range n {
+			f.walk(d, context, visit)
+		}
+	case []ast.Expr:
+		for i := range n {
+			f.walk(&n[i], context, visit)
+		}
+	case []ast.Stmt:
+		for _, s := range n {
+			f.walk(s, context, visit)
+		}
+	case []ast.Spec:
+		for _, s := range n {
+			f.walk(s, context, visit)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/cgo/doc.go b/third_party/gofrontend/libgo/go/cmd/cgo/doc.go
new file mode 100644
index 0000000..69c7ce8
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/cgo/doc.go
@@ -0,0 +1,748 @@
+// 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.
+
+/*
+
+Cgo enables the creation of Go packages that call C code.
+
+Using cgo with the go command
+
+To use cgo write normal Go code that imports a pseudo-package "C".
+The Go code can then refer to types such as C.size_t, variables such
+as C.stdout, or functions such as C.putchar.
+
+If the import of "C" is immediately preceded by a comment, that
+comment, called the preamble, is used as a header when compiling
+the C parts of the package.  For example:
+
+	// #include <stdio.h>
+	// #include <errno.h>
+	import "C"
+
+See $GOROOT/misc/cgo/stdio and $GOROOT/misc/cgo/gmp for examples.  See
+"C? Go? Cgo!" for an introduction to using cgo:
+http://golang.org/doc/articles/c_go_cgo.html.
+
+CFLAGS, CPPFLAGS, CXXFLAGS and LDFLAGS may be defined with pseudo #cgo
+directives within these comments to tweak the behavior of the C or C++
+compiler.  Values defined in multiple directives are concatenated
+together.  The directive can include a list of build constraints limiting its
+effect to systems satisfying one of the constraints
+(see http://golang.org/pkg/go/build/#hdr-Build_Constraints for details about the constraint syntax).
+For example:
+
+	// #cgo CFLAGS: -DPNG_DEBUG=1
+	// #cgo amd64 386 CFLAGS: -DX86=1
+	// #cgo LDFLAGS: -lpng
+	// #include <png.h>
+	import "C"
+
+Alternatively, CPPFLAGS and LDFLAGS may be obtained via the pkg-config
+tool using a '#cgo pkg-config:' directive followed by the package names.
+For example:
+
+	// #cgo pkg-config: png cairo
+	// #include <png.h>
+	import "C"
+
+When building, the CGO_CFLAGS, CGO_CPPFLAGS, CGO_CXXFLAGS and
+CGO_LDFLAGS environment variables are added to the flags derived from
+these directives.  Package-specific flags should be set using the
+directives, not the environment variables, so that builds work in
+unmodified environments.
+
+All the cgo CPPFLAGS and CFLAGS directives in a package are concatenated and
+used to compile C files in that package.  All the CPPFLAGS and CXXFLAGS
+directives in a package are concatenated and used to compile C++ files in that
+package.  All the LDFLAGS directives in any package in the program are
+concatenated and used at link time.  All the pkg-config directives are
+concatenated and sent to pkg-config simultaneously to add to each appropriate
+set of command-line flags.
+
+When the Go tool sees that one or more Go files use the special import
+"C", it will look for other non-Go files in the directory and compile
+them as part of the Go package.  Any .c, .s, or .S files will be
+compiled with the C compiler.  Any .cc, .cpp, or .cxx files will be
+compiled with the C++ compiler.  Any .h, .hh, .hpp, or .hxx files will
+not be compiled separately, but, if these header files are changed,
+the C and C++ files will be recompiled.  The default C and C++
+compilers may be changed by the CC and CXX environment variables,
+respectively; those environment variables may include command line
+options.
+
+To enable cgo during cross compiling builds, set the CGO_ENABLED
+environment variable to 1 when building the Go tools with make.bash.
+Also, set CC_FOR_TARGET to the C cross compiler for the target.  CC will
+be used for compiling for the host.
+
+After the Go tools are built, when running the go command, CC_FOR_TARGET is
+ignored.  The value of CC_FOR_TARGET when running make.bash is the default
+compiler.  However, you can set the environment variable CC, not CC_FOR_TARGET,
+to control the compiler when running the go tool.
+
+CXX_FOR_TARGET works in a similar way for C++ code.
+
+Go references to C
+
+Within the Go file, C's struct field names that are keywords in Go
+can be accessed by prefixing them with an underscore: if x points at a C
+struct with a field named "type", x._type accesses the field.
+C struct fields that cannot be expressed in Go, such as bit fields
+or misaligned data, are omitted in the Go struct, replaced by
+appropriate padding to reach the next field or the end of the struct.
+
+The standard C numeric types are available under the names
+C.char, C.schar (signed char), C.uchar (unsigned char),
+C.short, C.ushort (unsigned short), C.int, C.uint (unsigned int),
+C.long, C.ulong (unsigned long), C.longlong (long long),
+C.ulonglong (unsigned long long), C.float, C.double.
+The C type void* is represented by Go's unsafe.Pointer.
+
+To access a struct, union, or enum type directly, prefix it with
+struct_, union_, or enum_, as in C.struct_stat.
+
+As Go doesn't have support for C's union type in the general case,
+C's union types are represented as a Go byte array with the same length.
+
+Go structs cannot embed fields with C types.
+
+Cgo translates C types into equivalent unexported Go types.
+Because the translations are unexported, a Go package should not
+expose C types in its exported API: a C type used in one Go package
+is different from the same C type used in another.
+
+Any C function (even void functions) may be called in a multiple
+assignment context to retrieve both the return value (if any) and the
+C errno variable as an error (use _ to skip the result value if the
+function returns void).  For example:
+
+	n, err := C.sqrt(-1)
+	_, err := C.voidFunc()
+
+Calling C function pointers is currently not supported, however you can
+declare Go variables which hold C function pointers and pass them
+back and forth between Go and C. C code may call function pointers
+received from Go. For example:
+
+	package main
+
+	// typedef int (*intFunc) ();
+	//
+	// int
+	// bridge_int_func(intFunc f)
+	// {
+	//		return f();
+	// }
+	//
+	// int fortytwo()
+	// {
+	//	    return 42;
+	// }
+	import "C"
+	import "fmt"
+
+	func main() {
+		f := C.intFunc(C.fortytwo)
+		fmt.Println(int(C.bridge_int_func(f)))
+		// Output: 42
+	}
+
+In C, a function argument written as a fixed size array
+actually requires a pointer to the first element of the array.
+C compilers are aware of this calling convention and adjust
+the call accordingly, but Go cannot.  In Go, you must pass
+the pointer to the first element explicitly: C.f(&x[0]).
+
+A few special functions convert between Go and C types
+by making copies of the data.  In pseudo-Go definitions:
+
+	// Go string to C string
+	// The C string is allocated in the C heap using malloc.
+	// It is the caller's responsibility to arrange for it to be
+	// freed, such as by calling C.free (be sure to include stdlib.h
+	// if C.free is needed).
+	func C.CString(string) *C.char
+
+	// C string to Go string
+	func C.GoString(*C.char) string
+
+	// C string, length to Go string
+	func C.GoStringN(*C.char, C.int) string
+
+	// C pointer, length to Go []byte
+	func C.GoBytes(unsafe.Pointer, C.int) []byte
+
+C references to Go
+
+Go functions can be exported for use by C code in the following way:
+
+	//export MyFunction
+	func MyFunction(arg1, arg2 int, arg3 string) int64 {...}
+
+	//export MyFunction2
+	func MyFunction2(arg1, arg2 int, arg3 string) (int64, *C.char) {...}
+
+They will be available in the C code as:
+
+	extern int64 MyFunction(int arg1, int arg2, GoString arg3);
+	extern struct MyFunction2_return MyFunction2(int arg1, int arg2, GoString arg3);
+
+found in the _cgo_export.h generated header, after any preambles
+copied from the cgo input files. Functions with multiple
+return values are mapped to functions returning a struct.
+Not all Go types can be mapped to C types in a useful way.
+
+Using //export in a file places a restriction on the preamble:
+since it is copied into two different C output files, it must not
+contain any definitions, only declarations. Definitions must be
+placed in preambles in other files, or in C source files.
+
+Using cgo directly
+
+Usage:
+	go tool cgo [cgo options] [-- compiler options] file.go
+
+Cgo transforms the input file.go into four output files: two Go source
+files, a C file for 6c (or 8c or 5c), and a C file for gcc.
+
+The compiler options are passed through uninterpreted when
+invoking the C compiler to compile the C parts of the package.
+
+The following options are available when running cgo directly:
+
+	-dynimport file
+		Write list of symbols imported by file. Write to
+		-dynout argument or to standard output. Used by go
+		build when building a cgo package.
+	-dynout file
+		Write -dynimport output to file.
+	-dynlinker
+		Write dynamic linker as part of -dynimport output.
+	-godefs
+		Write out input file in Go syntax replacing C package
+		names with real values. Used to generate files in the
+		syscall package when bootstrapping a new target.
+	-cdefs
+		Like -godefs, but write file in C syntax.
+		Used to generate files in the runtime package when
+		bootstrapping a new target.
+	-objdir directory
+		Put all generated files in directory.
+	-gccgo
+		Generate output for the gccgo compiler rather than the
+		gc compiler.
+	-gccgoprefix prefix
+		The -fgo-prefix option to be used with gccgo.
+	-gccgopkgpath path
+		The -fgo-pkgpath option to be used with gccgo.
+	-import_runtime_cgo
+		If set (which it is by default) import runtime/cgo in
+		generated output.
+	-import_syscall
+		If set (which it is by default) import syscall in
+		generated output.
+	-debug-define
+		Debugging option. Print #defines.
+	-debug-gcc
+		Debugging option. Trace C compiler execution and output.
+*/
+package main
+
+/*
+Implementation details.
+
+Cgo provides a way for Go programs to call C code linked into the same
+address space. This comment explains the operation of cgo.
+
+Cgo reads a set of Go source files and looks for statements saying
+import "C". If the import has a doc comment, that comment is
+taken as literal C code to be used as a preamble to any C code
+generated by cgo. A typical preamble #includes necessary definitions:
+
+	// #include <stdio.h>
+	import "C"
+
+For more details about the usage of cgo, see the documentation
+comment at the top of this file.
+
+Understanding C
+
+Cgo scans the Go source files that import "C" for uses of that
+package, such as C.puts. It collects all such identifiers. The next
+step is to determine each kind of name. In C.xxx the xxx might refer
+to a type, a function, a constant, or a global variable. Cgo must
+decide which.
+
+The obvious thing for cgo to do is to process the preamble, expanding
+#includes and processing the corresponding C code. That would require
+a full C parser and type checker that was also aware of any extensions
+known to the system compiler (for example, all the GNU C extensions) as
+well as the system-specific header locations and system-specific
+pre-#defined macros. This is certainly possible to do, but it is an
+enormous amount of work.
+
+Cgo takes a different approach. It determines the meaning of C
+identifiers not by parsing C code but by feeding carefully constructed
+programs into the system C compiler and interpreting the generated
+error messages, debug information, and object files. In practice,
+parsing these is significantly less work and more robust than parsing
+C source.
+
+Cgo first invokes gcc -E -dM on the preamble, in order to find out
+about simple #defines for constants and the like. These are recorded
+for later use.
+
+Next, cgo needs to identify the kinds for each identifier. For the
+identifiers C.foo and C.bar, cgo generates this C program:
+
+	<preamble>
+	#line 1 "not-declared"
+	void __cgo_f_xxx_1(void) { __typeof__(foo) *__cgo_undefined__; }
+	#line 1 "not-type"
+	void __cgo_f_xxx_2(void) { foo *__cgo_undefined__; }
+	#line 1 "not-const"
+	void __cgo_f_xxx_3(void) { enum { __cgo_undefined__ = (foo)*1 }; }
+	#line 2 "not-declared"
+	void __cgo_f_xxx_1(void) { __typeof__(bar) *__cgo_undefined__; }
+	#line 2 "not-type"
+	void __cgo_f_xxx_2(void) { bar *__cgo_undefined__; }
+	#line 2 "not-const"
+	void __cgo_f_xxx_3(void) { enum { __cgo_undefined__ = (bar)*1 }; }
+
+This program will not compile, but cgo can use the presence or absence
+of an error message on a given line to deduce the information it
+needs. The program is syntactically valid regardless of whether each
+name is a type or an ordinary identifier, so there will be no syntax
+errors that might stop parsing early.
+
+An error on not-declared:1 indicates that foo is undeclared.
+An error on not-type:1 indicates that foo is not a type (if declared at all, it is an identifier).
+An error on not-const:1 indicates that foo is not an integer constant.
+
+The line number specifies the name involved. In the example, 1 is foo and 2 is bar.
+
+Next, cgo must learn the details of each type, variable, function, or
+constant. It can do this by reading object files. If cgo has decided
+that t1 is a type, v2 and v3 are variables or functions, and c4, c5,
+and c6 are constants, it generates:
+
+	<preamble>
+	__typeof__(t1) *__cgo__1;
+	__typeof__(v2) *__cgo__2;
+	__typeof__(v3) *__cgo__3;
+	__typeof__(c4) *__cgo__4;
+	enum { __cgo_enum__4 = c4 };
+	__typeof__(c5) *__cgo__5;
+	enum { __cgo_enum__5 = c5 };
+	__typeof__(c6) *__cgo__6;
+	enum { __cgo_enum__6 = c6 };
+
+	long long __cgo_debug_data[] = {
+		0, // t1
+		0, // v2
+		0, // v3
+		c4,
+		c5,
+		c6,
+		1
+	};
+
+and again invokes the system C compiler, to produce an object file
+containing debug information. Cgo parses the DWARF debug information
+for __cgo__N to learn the type of each identifier. (The types also
+distinguish functions from global variables.) If using a standard gcc,
+cgo can parse the DWARF debug information for the __cgo_enum__N to
+learn the identifier's value. The LLVM-based gcc on OS X emits
+incomplete DWARF information for enums; in that case cgo reads the
+constant values from the __cgo_debug_data from the object file's data
+segment.
+
+At this point cgo knows the meaning of each C.xxx well enough to start
+the translation process.
+
+Translating Go
+
+[The rest of this comment refers to 6g and 6c, the Go and C compilers
+that are part of the amd64 port of the gc Go toolchain. Everything here
+applies to another architecture's compilers as well.]
+
+Given the input Go files x.go and y.go, cgo generates these source
+files:
+
+	x.cgo1.go       # for 6g
+	y.cgo1.go       # for 6g
+	_cgo_gotypes.go # for 6g
+	_cgo_defun.c    # for 6c
+	x.cgo2.c        # for gcc
+	y.cgo2.c        # for gcc
+	_cgo_export.c   # for gcc
+	_cgo_main.c     # for gcc
+
+The file x.cgo1.go is a copy of x.go with the import "C" removed and
+references to C.xxx replaced with names like _Cfunc_xxx or _Ctype_xxx.
+The definitions of those identifiers, written as Go functions, types,
+or variables, are provided in _cgo_gotypes.go.
+
+Here is a _cgo_gotypes.go containing definitions for C.flush (provided
+in the preamble) and C.puts (from stdio):
+
+	type _Ctype_char int8
+	type _Ctype_int int32
+	type _Ctype_void [0]byte
+
+	func _Cfunc_CString(string) *_Ctype_char
+	func _Cfunc_flush() _Ctype_void
+	func _Cfunc_puts(*_Ctype_char) _Ctype_int
+
+For functions, cgo only writes an external declaration in the Go
+output. The implementation is in a combination of C for 6c (meaning
+any gc-toolchain compiler) and C for gcc.
+
+The 6c file contains the definitions of the functions. They all have
+similar bodies that invoke runtime·cgocall to make a switch from the
+Go runtime world to the system C (GCC-based) world.
+
+For example, here is the definition of _Cfunc_puts:
+
+	void _cgo_be59f0f25121_Cfunc_puts(void*);
+
+	void
+	·_Cfunc_puts(struct{uint8 x[1];}p)
+	{
+		runtime·cgocall(_cgo_be59f0f25121_Cfunc_puts, &p);
+	}
+
+The hexadecimal number is a hash of cgo's input, chosen to be
+deterministic yet unlikely to collide with other uses. The actual
+function _cgo_be59f0f25121_Cfunc_puts is implemented in a C source
+file compiled by gcc, the file x.cgo2.c:
+
+	void
+	_cgo_be59f0f25121_Cfunc_puts(void *v)
+	{
+		struct {
+			char* p0;
+			int r;
+			char __pad12[4];
+		} __attribute__((__packed__, __gcc_struct__)) *a = v;
+		a->r = puts((void*)a->p0);
+	}
+
+It extracts the arguments from the pointer to _Cfunc_puts's argument
+frame, invokes the system C function (in this case, puts), stores the
+result in the frame, and returns.
+
+Linking
+
+Once the _cgo_export.c and *.cgo2.c files have been compiled with gcc,
+they need to be linked into the final binary, along with the libraries
+they might depend on (in the case of puts, stdio). 6l has been
+extended to understand basic ELF files, but it does not understand ELF
+in the full complexity that modern C libraries embrace, so it cannot
+in general generate direct references to the system libraries.
+
+Instead, the build process generates an object file using dynamic
+linkage to the desired libraries. The main function is provided by
+_cgo_main.c:
+
+	int main() { return 0; }
+	void crosscall2(void(*fn)(void*, int), void *a, int c) { }
+	void _cgo_allocate(void *a, int c) { }
+	void _cgo_panic(void *a, int c) { }
+
+The extra functions here are stubs to satisfy the references in the C
+code generated for gcc. The build process links this stub, along with
+_cgo_export.c and *.cgo2.c, into a dynamic executable and then lets
+cgo examine the executable. Cgo records the list of shared library
+references and resolved names and writes them into a new file
+_cgo_import.c, which looks like:
+
+	#pragma cgo_dynamic_linker "/lib64/ld-linux-x86-64.so.2"
+	#pragma cgo_import_dynamic puts puts#GLIBC_2.2.5 "libc.so.6"
+	#pragma cgo_import_dynamic __libc_start_main __libc_start_main#GLIBC_2.2.5 "libc.so.6"
+	#pragma cgo_import_dynamic stdout stdout#GLIBC_2.2.5 "libc.so.6"
+	#pragma cgo_import_dynamic fflush fflush#GLIBC_2.2.5 "libc.so.6"
+	#pragma cgo_import_dynamic _ _ "libpthread.so.0"
+	#pragma cgo_import_dynamic _ _ "libc.so.6"
+
+In the end, the compiled Go package, which will eventually be
+presented to 6l as part of a larger program, contains:
+
+	_go_.6        # 6g-compiled object for _cgo_gotypes.go *.cgo1.go
+	_cgo_defun.6  # 6c-compiled object for _cgo_defun.c
+	_all.o        # gcc-compiled object for _cgo_export.c, *.cgo2.c
+	_cgo_import.6 # 6c-compiled object for _cgo_import.c
+
+The final program will be a dynamic executable, so that 6l can avoid
+needing to process arbitrary .o files. It only needs to process the .o
+files generated from C files that cgo writes, and those are much more
+limited in the ELF or other features that they use.
+
+In essence, the _cgo_import.6 file includes the extra linking
+directives that 6l is not sophisticated enough to derive from _all.o
+on its own. Similarly, the _all.o uses dynamic references to real
+system object code because 6l is not sophisticated enough to process
+the real code.
+
+The main benefits of this system are that 6l remains relatively simple
+(it does not need to implement a complete ELF and Mach-O linker) and
+that gcc is not needed after the package is compiled. For example,
+package net uses cgo for access to name resolution functions provided
+by libc. Although gcc is needed to compile package net, gcc is not
+needed to link programs that import package net.
+
+Runtime
+
+When using cgo, Go must not assume that it owns all details of the
+process. In particular it needs to coordinate with C in the use of
+threads and thread-local storage. The runtime package, in its own
+(6c-compiled) C code, declares a few uninitialized (default bss)
+variables:
+
+	bool	runtime·iscgo;
+	void	(*libcgo_thread_start)(void*);
+	void	(*initcgo)(G*);
+
+Any package using cgo imports "runtime/cgo", which provides
+initializations for these variables. It sets iscgo to 1, initcgo to a
+gcc-compiled function that can be called early during program startup,
+and libcgo_thread_start to a gcc-compiled function that can be used to
+create a new thread, in place of the runtime's usual direct system
+calls.
+
+Internal and External Linking
+
+The text above describes "internal" linking, in which 6l parses and
+links host object files (ELF, Mach-O, PE, and so on) into the final
+executable itself. Keeping 6l simple means we cannot possibly
+implement the full semantics of the host linker, so the kinds of
+objects that can be linked directly into the binary is limited (other
+code can only be used as a dynamic library). On the other hand, when
+using internal linking, 6l can generate Go binaries by itself.
+
+In order to allow linking arbitrary object files without requiring
+dynamic libraries, cgo will soon support an "external" linking mode
+too. In external linking mode, 6l does not process any host object
+files. Instead, it collects all the Go code and writes a single go.o
+object file containing it. Then it invokes the host linker (usually
+gcc) to combine the go.o object file and any supporting non-Go code
+into a final executable. External linking avoids the dynamic library
+requirement but introduces a requirement that the host linker be
+present to create such a binary.
+
+Most builds both compile source code and invoke the linker to create a
+binary. When cgo is involved, the compile step already requires gcc, so
+it is not problematic for the link step to require gcc too.
+
+An important exception is builds using a pre-compiled copy of the
+standard library. In particular, package net uses cgo on most systems,
+and we want to preserve the ability to compile pure Go code that
+imports net without requiring gcc to be present at link time. (In this
+case, the dynamic library requirement is less significant, because the
+only library involved is libc.so, which can usually be assumed
+present.)
+
+This conflict between functionality and the gcc requirement means we
+must support both internal and external linking, depending on the
+circumstances: if net is the only cgo-using package, then internal
+linking is probably fine, but if other packages are involved, so that there
+are dependencies on libraries beyond libc, external linking is likely
+to work better. The compilation of a package records the relevant
+information to support both linking modes, leaving the decision
+to be made when linking the final binary.
+
+Linking Directives
+
+In either linking mode, package-specific directives must be passed
+through to 6l. These are communicated by writing #pragma directives
+in a C source file compiled by 6c. The directives are copied into the .6 object file
+and then processed by the linker.
+
+The directives are:
+
+#pragma cgo_import_dynamic <local> [<remote> ["<library>"]]
+
+	In internal linking mode, allow an unresolved reference to
+	<local>, assuming it will be resolved by a dynamic library
+	symbol. The optional <remote> specifies the symbol's name and
+	possibly version in the dynamic library, and the optional "<library>"
+	names the specific library where the symbol should be found.
+
+	In the <remote>, # or @ can be used to introduce a symbol version.
+
+	Examples:
+	#pragma cgo_import_dynamic puts
+	#pragma cgo_import_dynamic puts puts#GLIBC_2.2.5
+	#pragma cgo_import_dynamic puts puts#GLIBC_2.2.5 "libc.so.6"
+
+	A side effect of the cgo_import_dynamic directive with a
+	library is to make the final binary depend on that dynamic
+	library. To get the dependency without importing any specific
+	symbols, use _ for local and remote.
+
+	Example:
+	#pragma cgo_import_dynamic _ _ "libc.so.6"
+
+	For compatibility with current versions of SWIG,
+	#pragma dynimport is an alias for #pragma cgo_import_dynamic.
+
+#pragma cgo_dynamic_linker "<path>"
+
+	In internal linking mode, use "<path>" as the dynamic linker
+	in the final binary. This directive is only needed from one
+	package when constructing a binary; by convention it is
+	supplied by runtime/cgo.
+
+	Example:
+	#pragma cgo_dynamic_linker "/lib/ld-linux.so.2"
+
+#pragma cgo_export_dynamic <local> <remote>
+
+	In internal linking mode, put the Go symbol
+	named <local> into the program's exported symbol table as
+	<remote>, so that C code can refer to it by that name. This
+	mechanism makes it possible for C code to call back into Go or
+	to share Go's data.
+
+	For compatibility with current versions of SWIG,
+	#pragma dynexport is an alias for #pragma cgo_export_dynamic.
+
+#pragma cgo_import_static <local>
+
+	In external linking mode, allow unresolved references to
+	<local> in the go.o object file prepared for the host linker,
+	under the assumption that <local> will be supplied by the
+	other object files that will be linked with go.o.
+
+	Example:
+	#pragma cgo_import_static puts_wrapper
+
+#pragma cgo_export_static <local> <remote>
+
+	In external linking mode, put the Go symbol
+	named <local> into the program's exported symbol table as
+	<remote>, so that C code can refer to it by that name. This
+	mechanism makes it possible for C code to call back into Go or
+	to share Go's data.
+
+#pragma cgo_ldflag "<arg>"
+
+	In external linking mode, invoke the host linker (usually gcc)
+	with "<arg>" as a command-line argument following the .o files.
+	Note that the arguments are for "gcc", not "ld".
+
+	Example:
+	#pragma cgo_ldflag "-lpthread"
+	#pragma cgo_ldflag "-L/usr/local/sqlite3/lib"
+
+A package compiled with cgo will include directives for both
+internal and external linking; the linker will select the appropriate
+subset for the chosen linking mode.
+
+Example
+
+As a simple example, consider a package that uses cgo to call C.sin.
+The following code will be generated by cgo:
+
+	// compiled by 6g
+
+	type _Ctype_double float64
+	func _Cfunc_sin(_Ctype_double) _Ctype_double
+
+	// compiled by 6c
+
+	#pragma cgo_import_dynamic sin sin#GLIBC_2.2.5 "libm.so.6"
+
+	#pragma cgo_import_static _cgo_gcc_Cfunc_sin
+	#pragma cgo_ldflag "-lm"
+
+	void _cgo_gcc_Cfunc_sin(void*);
+
+	void
+	·_Cfunc_sin(struct{uint8 x[16];}p)
+	{
+		runtime·cgocall(_cgo_gcc_Cfunc_sin, &p);
+	}
+
+	// compiled by gcc, into foo.cgo2.o
+
+	void
+	_cgo_gcc_Cfunc_sin(void *v)
+	{
+		struct {
+			double p0;
+			double r;
+		} __attribute__((__packed__)) *a = v;
+		a->r = sin(a->p0);
+	}
+
+What happens at link time depends on whether the final binary is linked
+using the internal or external mode. If other packages are compiled in
+"external only" mode, then the final link will be an external one.
+Otherwise the link will be an internal one.
+
+The directives in the 6c-compiled file are used according to the kind
+of final link used.
+
+In internal mode, 6l itself processes all the host object files, in
+particular foo.cgo2.o. To do so, it uses the cgo_import_dynamic and
+cgo_dynamic_linker directives to learn that the otherwise undefined
+reference to sin in foo.cgo2.o should be rewritten to refer to the
+symbol sin with version GLIBC_2.2.5 from the dynamic library
+"libm.so.6", and the binary should request "/lib/ld-linux.so.2" as its
+runtime dynamic linker.
+
+In external mode, 6l does not process any host object files, in
+particular foo.cgo2.o. It links together the 6g- and 6c-generated
+object files, along with any other Go code, into a go.o file. While
+doing that, 6l will discover that there is no definition for
+_cgo_gcc_Cfunc_sin, referred to by the 6c-compiled source file. This
+is okay, because 6l also processes the cgo_import_static directive and
+knows that _cgo_gcc_Cfunc_sin is expected to be supplied by a host
+object file, so 6l does not treat the missing symbol as an error when
+creating go.o. Indeed, the definition for _cgo_gcc_Cfunc_sin will be
+provided to the host linker by foo2.cgo.o, which in turn will need the
+symbol 'sin'. 6l also processes the cgo_ldflag directives, so that it
+knows that the eventual host link command must include the -lm
+argument, so that the host linker will be able to find 'sin' in the
+math library.
+
+6l Command Line Interface
+
+The go command and any other Go-aware build systems invoke 6l
+to link a collection of packages into a single binary. By default, 6l will
+present the same interface it does today:
+
+	6l main.a
+
+produces a file named 6.out, even if 6l does so by invoking the host
+linker in external linking mode.
+
+By default, 6l will decide the linking mode as follows: if the only
+packages using cgo are those on a whitelist of standard library
+packages (net, os/user, runtime/cgo), 6l will use internal linking
+mode. Otherwise, there are non-standard cgo packages involved, and 6l
+will use external linking mode. The first rule means that a build of
+the godoc binary, which uses net but no other cgo, can run without
+needing gcc available. The second rule means that a build of a
+cgo-wrapped library like sqlite3 can generate a standalone executable
+instead of needing to refer to a dynamic library. The specific choice
+can be overridden using a command line flag: 6l -linkmode=internal or
+6l -linkmode=external.
+
+In an external link, 6l will create a temporary directory, write any
+host object files found in package archives to that directory (renamed
+to avoid conflicts), write the go.o file to that directory, and invoke
+the host linker. The default value for the host linker is $CC, split
+into fields, or else "gcc". The specific host linker command line can
+be overridden using command line flags: 6l -extld=clang
+-extldflags='-ggdb -O3'.  If any package in a build includes a .cc or
+other file compiled by the C++ compiler, the go tool will use the
+-extld option to set the host linker to the C++ compiler.
+
+These defaults mean that Go-aware build systems can ignore the linking
+changes and keep running plain '6l' and get reasonable results, but
+they can also control the linking details if desired.
+
+*/
diff --git a/third_party/gofrontend/libgo/go/cmd/cgo/gcc.go b/third_party/gofrontend/libgo/go/cmd/cgo/gcc.go
new file mode 100644
index 0000000..f55cfba
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/cgo/gcc.go
@@ -0,0 +1,1728 @@
+// 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.
+
+// Annotate Ref in Prog with C types by parsing gcc debug output.
+// Conversion of debug output to Go types.
+
+package main
+
+import (
+	"bytes"
+	"debug/dwarf"
+	"debug/elf"
+	"debug/macho"
+	"debug/pe"
+	"encoding/binary"
+	"errors"
+	"flag"
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/token"
+	"os"
+	"strconv"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+)
+
+var debugDefine = flag.Bool("debug-define", false, "print relevant #defines")
+var debugGcc = flag.Bool("debug-gcc", false, "print gcc invocations")
+
+var nameToC = map[string]string{
+	"schar":         "signed char",
+	"uchar":         "unsigned char",
+	"ushort":        "unsigned short",
+	"uint":          "unsigned int",
+	"ulong":         "unsigned long",
+	"longlong":      "long long",
+	"ulonglong":     "unsigned long long",
+	"complexfloat":  "float complex",
+	"complexdouble": "double complex",
+}
+
+// cname returns the C name to use for C.s.
+// The expansions are listed in nameToC and also
+// struct_foo becomes "struct foo", and similarly for
+// union and enum.
+func cname(s string) string {
+	if t, ok := nameToC[s]; ok {
+		return t
+	}
+
+	if strings.HasPrefix(s, "struct_") {
+		return "struct " + s[len("struct_"):]
+	}
+	if strings.HasPrefix(s, "union_") {
+		return "union " + s[len("union_"):]
+	}
+	if strings.HasPrefix(s, "enum_") {
+		return "enum " + s[len("enum_"):]
+	}
+	if strings.HasPrefix(s, "sizeof_") {
+		return "sizeof(" + cname(s[len("sizeof_"):]) + ")"
+	}
+	return s
+}
+
+// DiscardCgoDirectives processes the import C preamble, and discards
+// all #cgo CFLAGS and LDFLAGS directives, so they don't make their
+// way into _cgo_export.h.
+func (f *File) DiscardCgoDirectives() {
+	linesIn := strings.Split(f.Preamble, "\n")
+	linesOut := make([]string, 0, len(linesIn))
+	for _, line := range linesIn {
+		l := strings.TrimSpace(line)
+		if len(l) < 5 || l[:4] != "#cgo" || !unicode.IsSpace(rune(l[4])) {
+			linesOut = append(linesOut, line)
+		} else {
+			linesOut = append(linesOut, "")
+		}
+	}
+	f.Preamble = strings.Join(linesOut, "\n")
+}
+
+// addToFlag appends args to flag.  All flags are later written out onto the
+// _cgo_flags file for the build system to use.
+func (p *Package) addToFlag(flag string, args []string) {
+	p.CgoFlags[flag] = append(p.CgoFlags[flag], args...)
+	if flag == "CFLAGS" {
+		// We'll also need these when preprocessing for dwarf information.
+		p.GccOptions = append(p.GccOptions, args...)
+	}
+}
+
+// splitQuoted splits the string s around each instance of one or more consecutive
+// white space characters while taking into account quotes and escaping, and
+// returns an array of substrings of s or an empty list if s contains only white space.
+// Single quotes and double quotes are recognized to prevent splitting within the
+// quoted region, and are removed from the resulting substrings. If a quote in s
+// isn't closed err will be set and r will have the unclosed argument as the
+// last element.  The backslash is used for escaping.
+//
+// For example, the following string:
+//
+//     `a b:"c d" 'e''f'  "g\""`
+//
+// Would be parsed as:
+//
+//     []string{"a", "b:c d", "ef", `g"`}
+//
+func splitQuoted(s string) (r []string, err error) {
+	var args []string
+	arg := make([]rune, len(s))
+	escaped := false
+	quoted := false
+	quote := '\x00'
+	i := 0
+	for _, r := range s {
+		switch {
+		case escaped:
+			escaped = false
+		case r == '\\':
+			escaped = true
+			continue
+		case quote != 0:
+			if r == quote {
+				quote = 0
+				continue
+			}
+		case r == '"' || r == '\'':
+			quoted = true
+			quote = r
+			continue
+		case unicode.IsSpace(r):
+			if quoted || i > 0 {
+				quoted = false
+				args = append(args, string(arg[:i]))
+				i = 0
+			}
+			continue
+		}
+		arg[i] = r
+		i++
+	}
+	if quoted || i > 0 {
+		args = append(args, string(arg[:i]))
+	}
+	if quote != 0 {
+		err = errors.New("unclosed quote")
+	} else if escaped {
+		err = errors.New("unfinished escaping")
+	}
+	return args, err
+}
+
+var safeBytes = []byte(`+-.,/0123456789:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\_abcdefghijklmnopqrstuvwxyz`)
+
+func safeName(s string) bool {
+	if s == "" {
+		return false
+	}
+	for i := 0; i < len(s); i++ {
+		if c := s[i]; c < 0x80 && bytes.IndexByte(safeBytes, c) < 0 {
+			return false
+		}
+	}
+	return true
+}
+
+// Translate rewrites f.AST, the original Go input, to remove
+// references to the imported package C, replacing them with
+// references to the equivalent Go types, functions, and variables.
+func (p *Package) Translate(f *File) {
+	for _, cref := range f.Ref {
+		// Convert C.ulong to C.unsigned long, etc.
+		cref.Name.C = cname(cref.Name.Go)
+	}
+	p.loadDefines(f)
+	needType := p.guessKinds(f)
+	if len(needType) > 0 {
+		p.loadDWARF(f, needType)
+	}
+	p.rewriteRef(f)
+}
+
+// loadDefines coerces gcc into spitting out the #defines in use
+// in the file f and saves relevant renamings in f.Name[name].Define.
+func (p *Package) loadDefines(f *File) {
+	var b bytes.Buffer
+	b.WriteString(f.Preamble)
+	b.WriteString(builtinProlog)
+	stdout := p.gccDefines(b.Bytes())
+
+	for _, line := range strings.Split(stdout, "\n") {
+		if len(line) < 9 || line[0:7] != "#define" {
+			continue
+		}
+
+		line = strings.TrimSpace(line[8:])
+
+		var key, val string
+		spaceIndex := strings.Index(line, " ")
+		tabIndex := strings.Index(line, "\t")
+
+		if spaceIndex == -1 && tabIndex == -1 {
+			continue
+		} else if tabIndex == -1 || (spaceIndex != -1 && spaceIndex < tabIndex) {
+			key = line[0:spaceIndex]
+			val = strings.TrimSpace(line[spaceIndex:])
+		} else {
+			key = line[0:tabIndex]
+			val = strings.TrimSpace(line[tabIndex:])
+		}
+
+		if n := f.Name[key]; n != nil {
+			if *debugDefine {
+				fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val)
+			}
+			n.Define = val
+		}
+	}
+}
+
+// guessKinds tricks gcc into revealing the kind of each
+// name xxx for the references C.xxx in the Go input.
+// The kind is either a constant, type, or variable.
+func (p *Package) guessKinds(f *File) []*Name {
+	// Determine kinds for names we already know about,
+	// like #defines or 'struct foo', before bothering with gcc.
+	var names, needType []*Name
+	for _, n := range f.Name {
+		// If we've already found this name as a #define
+		// and we can translate it as a constant value, do so.
+		if n.Define != "" {
+			isConst := false
+			if _, err := strconv.Atoi(n.Define); err == nil {
+				isConst = true
+			} else if n.Define[0] == '"' || n.Define[0] == '\'' {
+				if _, err := parser.ParseExpr(n.Define); err == nil {
+					isConst = true
+				}
+			}
+			if isConst {
+				n.Kind = "const"
+				// Turn decimal into hex, just for consistency
+				// with enum-derived constants.  Otherwise
+				// in the cgo -godefs output half the constants
+				// are in hex and half are in whatever the #define used.
+				i, err := strconv.ParseInt(n.Define, 0, 64)
+				if err == nil {
+					n.Const = fmt.Sprintf("%#x", i)
+				} else {
+					n.Const = n.Define
+				}
+				continue
+			}
+
+			if isName(n.Define) {
+				n.C = n.Define
+			}
+		}
+
+		needType = append(needType, n)
+
+		// If this is a struct, union, or enum type name, no need to guess the kind.
+		if strings.HasPrefix(n.C, "struct ") || strings.HasPrefix(n.C, "union ") || strings.HasPrefix(n.C, "enum ") {
+			n.Kind = "type"
+			continue
+		}
+
+		// Otherwise, we'll need to find out from gcc.
+		names = append(names, n)
+	}
+
+	// Bypass gcc if there's nothing left to find out.
+	if len(names) == 0 {
+		return needType
+	}
+
+	// Coerce gcc into telling us whether each name is a type, a value, or undeclared.
+	// For names, find out whether they are integer constants.
+	// We used to look at specific warning or error messages here, but that tied the
+	// behavior too closely to specific versions of the compilers.
+	// Instead, arrange that we can infer what we need from only the presence or absence
+	// of an error on a specific line.
+	//
+	// For each name, we generate these lines, where xxx is the index in toSniff plus one.
+	//
+	//	#line xxx "not-declared"
+	//	void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__; }
+	//	#line xxx "not-type"
+	//	void __cgo_f_xxx_2(void) { name *__cgo_undefined__; }
+	//	#line xxx "not-const"
+	//	void __cgo_f_xxx_3(void) { enum { __cgo_undefined__ = (name)*1 }; }
+	//
+	// If we see an error at not-declared:xxx, the corresponding name is not declared.
+	// If we see an error at not-type:xxx, the corresponding name is a type.
+	// If we see an error at not-const:xxx, the corresponding name is not an integer constant.
+	// If we see no errors, we assume the name is an expression but not a constant
+	// (so a variable or a function).
+	//
+	// The specific input forms are chosen so that they are valid C syntax regardless of
+	// whether name denotes a type or an expression.
+
+	var b bytes.Buffer
+	b.WriteString(f.Preamble)
+	b.WriteString(builtinProlog)
+
+	for i, n := range names {
+		fmt.Fprintf(&b, "#line %d \"not-declared\"\n"+
+			"void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__; }\n"+
+			"#line %d \"not-type\"\n"+
+			"void __cgo_f_%d_2(void) { %s *__cgo_undefined__; }\n"+
+			"#line %d \"not-const\"\n"+
+			"void __cgo_f_%d_3(void) { enum { __cgo__undefined__ = (%s)*1 }; }\n",
+			i+1, i+1, n.C,
+			i+1, i+1, n.C,
+			i+1, i+1, n.C)
+	}
+	fmt.Fprintf(&b, "#line 1 \"completed\"\n"+
+		"int __cgo__1 = __cgo__2;\n")
+
+	stderr := p.gccErrors(b.Bytes())
+	if stderr == "" {
+		fatalf("%s produced no output\non input:\n%s", p.gccBaseCmd()[0], b.Bytes())
+	}
+
+	completed := false
+	sniff := make([]int, len(names))
+	const (
+		notType = 1 << iota
+		notConst
+	)
+	for _, line := range strings.Split(stderr, "\n") {
+		if !strings.Contains(line, ": error:") {
+			// we only care about errors.
+			// we tried to turn off warnings on the command line, but one never knows.
+			continue
+		}
+
+		c1 := strings.Index(line, ":")
+		if c1 < 0 {
+			continue
+		}
+		c2 := strings.Index(line[c1+1:], ":")
+		if c2 < 0 {
+			continue
+		}
+		c2 += c1 + 1
+
+		filename := line[:c1]
+		i, _ := strconv.Atoi(line[c1+1 : c2])
+		i--
+		if i < 0 || i >= len(names) {
+			continue
+		}
+
+		switch filename {
+		case "completed":
+			// Strictly speaking, there is no guarantee that seeing the error at completed:1
+			// (at the end of the file) means we've seen all the errors from earlier in the file,
+			// but usually it does. Certainly if we don't see the completed:1 error, we did
+			// not get all the errors we expected.
+			completed = true
+
+		case "not-declared":
+			error_(token.NoPos, "%s", strings.TrimSpace(line[c2+1:]))
+		case "not-type":
+			sniff[i] |= notType
+		case "not-const":
+			sniff[i] |= notConst
+		}
+	}
+
+	if !completed {
+		fatalf("%s did not produce error at completed:1\non input:\n%s", p.gccBaseCmd()[0], b.Bytes())
+	}
+
+	for i, n := range names {
+		switch sniff[i] {
+		case 0:
+			error_(token.NoPos, "could not determine kind of name for C.%s", fixGo(n.Go))
+		case notType:
+			n.Kind = "const"
+		case notConst:
+			n.Kind = "type"
+		case notConst | notType:
+			n.Kind = "not-type"
+		}
+	}
+	if nerrors > 0 {
+		fatalf("unresolved names")
+	}
+
+	needType = append(needType, names...)
+	return needType
+}
+
+// loadDWARF parses the DWARF debug information generated
+// by gcc to learn the details of the constants, variables, and types
+// being referred to as C.xxx.
+func (p *Package) loadDWARF(f *File, names []*Name) {
+	// Extract the types from the DWARF section of an object
+	// from a well-formed C program.  Gcc only generates DWARF info
+	// for symbols in the object file, so it is not enough to print the
+	// preamble and hope the symbols we care about will be there.
+	// Instead, emit
+	//	__typeof__(names[i]) *__cgo__i;
+	// for each entry in names and then dereference the type we
+	// learn for __cgo__i.
+	var b bytes.Buffer
+	b.WriteString(f.Preamble)
+	b.WriteString(builtinProlog)
+	for i, n := range names {
+		fmt.Fprintf(&b, "__typeof__(%s) *__cgo__%d;\n", n.C, i)
+		if n.Kind == "const" {
+			fmt.Fprintf(&b, "enum { __cgo_enum__%d = %s };\n", i, n.C)
+		}
+	}
+
+	// Apple's LLVM-based gcc does not include the enumeration
+	// names and values in its DWARF debug output.  In case we're
+	// using such a gcc, create a data block initialized with the values.
+	// We can read them out of the object file.
+	fmt.Fprintf(&b, "long long __cgodebug_data[] = {\n")
+	for _, n := range names {
+		if n.Kind == "const" {
+			fmt.Fprintf(&b, "\t%s,\n", n.C)
+		} else {
+			fmt.Fprintf(&b, "\t0,\n")
+		}
+	}
+	// for the last entry, we can not use 0, otherwise
+	// in case all __cgodebug_data is zero initialized,
+	// LLVM-based gcc will place the it in the __DATA.__common
+	// zero-filled section (our debug/macho doesn't support
+	// this)
+	fmt.Fprintf(&b, "\t1\n")
+	fmt.Fprintf(&b, "};\n")
+
+	d, bo, debugData := p.gccDebug(b.Bytes())
+	enumVal := make([]int64, len(debugData)/8)
+	for i := range enumVal {
+		enumVal[i] = int64(bo.Uint64(debugData[i*8:]))
+	}
+
+	// Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i.
+	types := make([]dwarf.Type, len(names))
+	enums := make([]dwarf.Offset, len(names))
+	nameToIndex := make(map[*Name]int)
+	for i, n := range names {
+		nameToIndex[n] = i
+	}
+	nameToRef := make(map[*Name]*Ref)
+	for _, ref := range f.Ref {
+		nameToRef[ref.Name] = ref
+	}
+	r := d.Reader()
+	for {
+		e, err := r.Next()
+		if err != nil {
+			fatalf("reading DWARF entry: %s", err)
+		}
+		if e == nil {
+			break
+		}
+		switch e.Tag {
+		case dwarf.TagEnumerationType:
+			offset := e.Offset
+			for {
+				e, err := r.Next()
+				if err != nil {
+					fatalf("reading DWARF entry: %s", err)
+				}
+				if e.Tag == 0 {
+					break
+				}
+				if e.Tag == dwarf.TagEnumerator {
+					entryName := e.Val(dwarf.AttrName).(string)
+					if strings.HasPrefix(entryName, "__cgo_enum__") {
+						n, _ := strconv.Atoi(entryName[len("__cgo_enum__"):])
+						if 0 <= n && n < len(names) {
+							enums[n] = offset
+						}
+					}
+				}
+			}
+		case dwarf.TagVariable:
+			name, _ := e.Val(dwarf.AttrName).(string)
+			typOff, _ := e.Val(dwarf.AttrType).(dwarf.Offset)
+			if name == "" || typOff == 0 {
+				fatalf("malformed DWARF TagVariable entry")
+			}
+			if !strings.HasPrefix(name, "__cgo__") {
+				break
+			}
+			typ, err := d.Type(typOff)
+			if err != nil {
+				fatalf("loading DWARF type: %s", err)
+			}
+			t, ok := typ.(*dwarf.PtrType)
+			if !ok || t == nil {
+				fatalf("internal error: %s has non-pointer type", name)
+			}
+			i, err := strconv.Atoi(name[7:])
+			if err != nil {
+				fatalf("malformed __cgo__ name: %s", name)
+			}
+			if enums[i] != 0 {
+				t, err := d.Type(enums[i])
+				if err != nil {
+					fatalf("loading DWARF type: %s", err)
+				}
+				types[i] = t
+			} else {
+				types[i] = t.Type
+			}
+		}
+		if e.Tag != dwarf.TagCompileUnit {
+			r.SkipChildren()
+		}
+	}
+
+	// Record types and typedef information.
+	var conv typeConv
+	conv.Init(p.PtrSize, p.IntSize)
+	for i, n := range names {
+		if types[i] == nil {
+			continue
+		}
+		pos := token.NoPos
+		if ref, ok := nameToRef[n]; ok {
+			pos = ref.Pos()
+		}
+		f, fok := types[i].(*dwarf.FuncType)
+		if n.Kind != "type" && fok {
+			n.Kind = "func"
+			n.FuncType = conv.FuncType(f, pos)
+		} else {
+			n.Type = conv.Type(types[i], pos)
+			if enums[i] != 0 && n.Type.EnumValues != nil {
+				k := fmt.Sprintf("__cgo_enum__%d", i)
+				n.Kind = "const"
+				n.Const = fmt.Sprintf("%#x", n.Type.EnumValues[k])
+				// Remove injected enum to ensure the value will deep-compare
+				// equally in future loads of the same constant.
+				delete(n.Type.EnumValues, k)
+			}
+			// Prefer debug data over DWARF debug output, if we have it.
+			if n.Kind == "const" && i < len(enumVal) {
+				n.Const = fmt.Sprintf("%#x", enumVal[i])
+			}
+		}
+		conv.FinishType(pos)
+	}
+}
+
+// mangleName does name mangling to translate names
+// from the original Go source files to the names
+// used in the final Go files generated by cgo.
+func (p *Package) mangleName(n *Name) {
+	// When using gccgo variables have to be
+	// exported so that they become global symbols
+	// that the C code can refer to.
+	prefix := "_C"
+	if *gccgo && n.IsVar() {
+		prefix = "C"
+	}
+	n.Mangle = prefix + n.Kind + "_" + n.Go
+}
+
+// rewriteRef rewrites all the C.xxx references in f.AST to refer to the
+// Go equivalents, now that we have figured out the meaning of all
+// the xxx.  In *godefs or *cdefs mode, rewriteRef replaces the names
+// with full definitions instead of mangled names.
+func (p *Package) rewriteRef(f *File) {
+	// Keep a list of all the functions, to remove the ones
+	// only used as expressions and avoid generating bridge
+	// code for them.
+	functions := make(map[string]bool)
+
+	// Assign mangled names.
+	for _, n := range f.Name {
+		if n.Kind == "not-type" {
+			n.Kind = "var"
+		}
+		if n.Mangle == "" {
+			p.mangleName(n)
+		}
+		if n.Kind == "func" {
+			functions[n.Go] = false
+		}
+	}
+
+	// Now that we have all the name types filled in,
+	// scan through the Refs to identify the ones that
+	// are trying to do a ,err call.  Also check that
+	// functions are only used in calls.
+	for _, r := range f.Ref {
+		if r.Name.Kind == "const" && r.Name.Const == "" {
+			error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go))
+		}
+		var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default
+		switch r.Context {
+		case "call", "call2":
+			if r.Name.Kind != "func" {
+				if r.Name.Kind == "type" {
+					r.Context = "type"
+					expr = r.Name.Type.Go
+					break
+				}
+				error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go))
+				break
+			}
+			functions[r.Name.Go] = true
+			if r.Context == "call2" {
+				if r.Name.Go == "_CMalloc" {
+					error_(r.Pos(), "no two-result form for C.malloc")
+					break
+				}
+				// Invent new Name for the two-result function.
+				n := f.Name["2"+r.Name.Go]
+				if n == nil {
+					n = new(Name)
+					*n = *r.Name
+					n.AddError = true
+					n.Mangle = "_C2func_" + n.Go
+					f.Name["2"+r.Name.Go] = n
+				}
+				expr = ast.NewIdent(n.Mangle)
+				r.Name = n
+				break
+			}
+		case "expr":
+			if r.Name.Kind == "func" {
+				// Function is being used in an expression, to e.g. pass around a C function pointer.
+				// Create a new Name for this Ref which causes the variable to be declared in Go land.
+				fpName := "fp_" + r.Name.Go
+				name := f.Name[fpName]
+				if name == nil {
+					name = &Name{
+						Go:   fpName,
+						C:    r.Name.C,
+						Kind: "fpvar",
+						Type: &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*"), Go: ast.NewIdent("unsafe.Pointer")},
+					}
+					p.mangleName(name)
+					f.Name[fpName] = name
+				}
+				r.Name = name
+				expr = ast.NewIdent(name.Mangle)
+			} else if r.Name.Kind == "type" {
+				// Okay - might be new(T)
+				expr = r.Name.Type.Go
+			} else if r.Name.Kind == "var" {
+				expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
+			}
+
+		case "type":
+			if r.Name.Kind != "type" {
+				error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go))
+			} else if r.Name.Type == nil {
+				// Use of C.enum_x, C.struct_x or C.union_x without C definition.
+				// GCC won't raise an error when using pointers to such unknown types.
+				error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
+			} else {
+				expr = r.Name.Type.Go
+			}
+		default:
+			if r.Name.Kind == "func" {
+				error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go))
+			}
+		}
+		if *godefs || *cdefs {
+			// Substitute definition for mangled type name.
+			if id, ok := expr.(*ast.Ident); ok {
+				if t := typedef[id.Name]; t != nil {
+					expr = t.Go
+				}
+				if id.Name == r.Name.Mangle && r.Name.Const != "" {
+					expr = ast.NewIdent(r.Name.Const)
+				}
+			}
+		}
+
+		// Copy position information from old expr into new expr,
+		// in case expression being replaced is first on line.
+		// See golang.org/issue/6563.
+		pos := (*r.Expr).Pos()
+		switch x := expr.(type) {
+		case *ast.Ident:
+			expr = &ast.Ident{NamePos: pos, Name: x.Name}
+		}
+
+		*r.Expr = expr
+	}
+
+	// Remove functions only used as expressions, so their respective
+	// bridge functions are not generated.
+	for name, used := range functions {
+		if !used {
+			delete(f.Name, name)
+		}
+	}
+}
+
+// gccBaseCmd returns the start of the compiler command line.
+// It uses $CC if set, or else $GCC, or else the compiler recorded
+// during the initial build as defaultCC.
+// defaultCC is defined in zdefaultcc.go, written by cmd/dist.
+func (p *Package) gccBaseCmd() []string {
+	// Use $CC if set, since that's what the build uses.
+	if ret := strings.Fields(os.Getenv("CC")); len(ret) > 0 {
+		return ret
+	}
+	// Try $GCC if set, since that's what we used to use.
+	if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 {
+		return ret
+	}
+	return strings.Fields(defaultCC)
+}
+
+// gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
+func (p *Package) gccMachine() []string {
+	switch goarch {
+	case "amd64":
+		return []string{"-m64"}
+	case "386":
+		return []string{"-m32"}
+	case "arm":
+		return []string{"-marm"} // not thumb
+	}
+	return nil
+}
+
+func gccTmp() string {
+	return *objDir + "_cgo_.o"
+}
+
+// gccCmd returns the gcc command line to use for compiling
+// the input.
+func (p *Package) gccCmd() []string {
+	c := append(p.gccBaseCmd(),
+		"-w",          // no warnings
+		"-Wno-error",  // warnings are not errors
+		"-o"+gccTmp(), // write object to tmp
+		"-gdwarf-2",   // generate DWARF v2 debugging symbols
+		"-c",          // do not link
+		"-xc",         // input language is C
+	)
+	if strings.Contains(c[0], "clang") {
+		c = append(c,
+			"-ferror-limit=0",
+			// Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
+			// doesn't have -Wno-unneeded-internal-declaration, so we need yet another
+			// flag to disable the warning. Yes, really good diagnostics, clang.
+			"-Wno-unknown-warning-option",
+			"-Wno-unneeded-internal-declaration",
+			"-Wno-unused-function",
+			"-Qunused-arguments",
+			// Clang embeds prototypes for some builtin functions,
+			// like malloc and calloc, but all size_t parameters are
+			// incorrectly typed unsigned long. We work around that
+			// by disabling the builtin functions (this is safe as
+			// it won't affect the actual compilation of the C code).
+			// See: http://golang.org/issue/6506.
+			"-fno-builtin",
+		)
+	}
+
+	c = append(c, p.GccOptions...)
+	c = append(c, p.gccMachine()...)
+	c = append(c, "-") //read input from standard input
+	return c
+}
+
+// gccDebug runs gcc -gdwarf-2 over the C program stdin and
+// returns the corresponding DWARF data and, if present, debug data block.
+func (p *Package) gccDebug(stdin []byte) (*dwarf.Data, binary.ByteOrder, []byte) {
+	runGcc(stdin, p.gccCmd())
+
+	isDebugData := func(s string) bool {
+		// Some systems use leading _ to denote non-assembly symbols.
+		return s == "__cgodebug_data" || s == "___cgodebug_data"
+	}
+
+	if f, err := macho.Open(gccTmp()); err == nil {
+		defer f.Close()
+		d, err := f.DWARF()
+		if err != nil {
+			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
+		}
+		var data []byte
+		if f.Symtab != nil {
+			for i := range f.Symtab.Syms {
+				s := &f.Symtab.Syms[i]
+				if isDebugData(s.Name) {
+					// Found it.  Now find data section.
+					if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
+						sect := f.Sections[i]
+						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
+							if sdat, err := sect.Data(); err == nil {
+								data = sdat[s.Value-sect.Addr:]
+							}
+						}
+					}
+				}
+			}
+		}
+		return d, f.ByteOrder, data
+	}
+
+	if f, err := elf.Open(gccTmp()); err == nil {
+		defer f.Close()
+		d, err := f.DWARF()
+		if err != nil {
+			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
+		}
+		var data []byte
+		symtab, err := f.Symbols()
+		if err == nil {
+			for i := range symtab {
+				s := &symtab[i]
+				if isDebugData(s.Name) {
+					// Found it.  Now find data section.
+					if i := int(s.Section); 0 <= i && i < len(f.Sections) {
+						sect := f.Sections[i]
+						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
+							if sdat, err := sect.Data(); err == nil {
+								data = sdat[s.Value-sect.Addr:]
+							}
+						}
+					}
+				}
+			}
+		}
+		return d, f.ByteOrder, data
+	}
+
+	if f, err := pe.Open(gccTmp()); err == nil {
+		defer f.Close()
+		d, err := f.DWARF()
+		if err != nil {
+			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
+		}
+		var data []byte
+		for _, s := range f.Symbols {
+			if isDebugData(s.Name) {
+				if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
+					sect := f.Sections[i]
+					if s.Value < sect.Size {
+						if sdat, err := sect.Data(); err == nil {
+							data = sdat[s.Value:]
+						}
+					}
+				}
+			}
+		}
+		return d, binary.LittleEndian, data
+	}
+
+	fatalf("cannot parse gcc output %s as ELF, Mach-O, PE object", gccTmp())
+	panic("not reached")
+}
+
+// gccDefines runs gcc -E -dM -xc - over the C program stdin
+// and returns the corresponding standard output, which is the
+// #defines that gcc encountered while processing the input
+// and its included files.
+func (p *Package) gccDefines(stdin []byte) string {
+	base := append(p.gccBaseCmd(), "-E", "-dM", "-xc")
+	base = append(base, p.gccMachine()...)
+	stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
+	return stdout
+}
+
+// gccErrors runs gcc over the C program stdin and returns
+// the errors that gcc prints.  That is, this function expects
+// gcc to fail.
+func (p *Package) gccErrors(stdin []byte) string {
+	// TODO(rsc): require failure
+	args := p.gccCmd()
+
+	if *debugGcc {
+		fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " "))
+		os.Stderr.Write(stdin)
+		fmt.Fprint(os.Stderr, "EOF\n")
+	}
+	stdout, stderr, _ := run(stdin, args)
+	if *debugGcc {
+		os.Stderr.Write(stdout)
+		os.Stderr.Write(stderr)
+	}
+	return string(stderr)
+}
+
+// runGcc runs the gcc command line args with stdin on standard input.
+// If the command exits with a non-zero exit status, runGcc prints
+// details about what was run and exits.
+// Otherwise runGcc returns the data written to standard output and standard error.
+// Note that for some of the uses we expect useful data back
+// on standard error, but for those uses gcc must still exit 0.
+func runGcc(stdin []byte, args []string) (string, string) {
+	if *debugGcc {
+		fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " "))
+		os.Stderr.Write(stdin)
+		fmt.Fprint(os.Stderr, "EOF\n")
+	}
+	stdout, stderr, ok := run(stdin, args)
+	if *debugGcc {
+		os.Stderr.Write(stdout)
+		os.Stderr.Write(stderr)
+	}
+	if !ok {
+		os.Stderr.Write(stderr)
+		os.Exit(2)
+	}
+	return string(stdout), string(stderr)
+}
+
+// A typeConv is a translator from dwarf types to Go types
+// with equivalent memory layout.
+type typeConv struct {
+	// Cache of already-translated or in-progress types.
+	m       map[dwarf.Type]*Type
+	typedef map[string]ast.Expr
+
+	// Map from types to incomplete pointers to those types.
+	ptrs map[dwarf.Type][]*Type
+
+	// Fields to be processed by godefsField after completing pointers.
+	todoFlds [][]*ast.Field
+
+	// Predeclared types.
+	bool                                   ast.Expr
+	byte                                   ast.Expr // denotes padding
+	int8, int16, int32, int64              ast.Expr
+	uint8, uint16, uint32, uint64, uintptr ast.Expr
+	float32, float64                       ast.Expr
+	complex64, complex128                  ast.Expr
+	void                                   ast.Expr
+	unsafePointer                          ast.Expr
+	string                                 ast.Expr
+	goVoid                                 ast.Expr // _Ctype_void, denotes C's void
+
+	ptrSize int64
+	intSize int64
+}
+
+var tagGen int
+var typedef = make(map[string]*Type)
+var goIdent = make(map[string]*ast.Ident)
+
+func (c *typeConv) Init(ptrSize, intSize int64) {
+	c.ptrSize = ptrSize
+	c.intSize = intSize
+	c.m = make(map[dwarf.Type]*Type)
+	c.ptrs = make(map[dwarf.Type][]*Type)
+	c.bool = c.Ident("bool")
+	c.byte = c.Ident("byte")
+	c.int8 = c.Ident("int8")
+	c.int16 = c.Ident("int16")
+	c.int32 = c.Ident("int32")
+	c.int64 = c.Ident("int64")
+	c.uint8 = c.Ident("uint8")
+	c.uint16 = c.Ident("uint16")
+	c.uint32 = c.Ident("uint32")
+	c.uint64 = c.Ident("uint64")
+	c.uintptr = c.Ident("uintptr")
+	c.float32 = c.Ident("float32")
+	c.float64 = c.Ident("float64")
+	c.complex64 = c.Ident("complex64")
+	c.complex128 = c.Ident("complex128")
+	c.unsafePointer = c.Ident("unsafe.Pointer")
+	c.void = c.Ident("void")
+	c.string = c.Ident("string")
+	c.goVoid = c.Ident("_Ctype_void")
+}
+
+// base strips away qualifiers and typedefs to get the underlying type
+func base(dt dwarf.Type) dwarf.Type {
+	for {
+		if d, ok := dt.(*dwarf.QualType); ok {
+			dt = d.Type
+			continue
+		}
+		if d, ok := dt.(*dwarf.TypedefType); ok {
+			dt = d.Type
+			continue
+		}
+		break
+	}
+	return dt
+}
+
+// Map from dwarf text names to aliases we use in package "C".
+var dwarfToName = map[string]string{
+	"long int":               "long",
+	"long unsigned int":      "ulong",
+	"unsigned int":           "uint",
+	"short unsigned int":     "ushort",
+	"short int":              "short",
+	"long long int":          "longlong",
+	"long long unsigned int": "ulonglong",
+	"signed char":            "schar",
+	"float complex":          "complexfloat",
+	"double complex":         "complexdouble",
+}
+
+const signedDelta = 64
+
+// String returns the current type representation.  Format arguments
+// are assembled within this method so that any changes in mutable
+// values are taken into account.
+func (tr *TypeRepr) String() string {
+	if len(tr.Repr) == 0 {
+		return ""
+	}
+	if len(tr.FormatArgs) == 0 {
+		return tr.Repr
+	}
+	return fmt.Sprintf(tr.Repr, tr.FormatArgs...)
+}
+
+// Empty returns true if the result of String would be "".
+func (tr *TypeRepr) Empty() bool {
+	return len(tr.Repr) == 0
+}
+
+// Set modifies the type representation.
+// If fargs are provided, repr is used as a format for fmt.Sprintf.
+// Otherwise, repr is used unprocessed as the type representation.
+func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
+	tr.Repr = repr
+	tr.FormatArgs = fargs
+}
+
+// FinishType completes any outstanding type mapping work.
+// In particular, it resolves incomplete pointer types and also runs
+// godefsFields on any new struct types.
+func (c *typeConv) FinishType(pos token.Pos) {
+	// Completing one pointer type might produce more to complete.
+	// Keep looping until they're all done.
+	for len(c.ptrs) > 0 {
+		for dtype := range c.ptrs {
+			// Note Type might invalidate c.ptrs[dtype].
+			t := c.Type(dtype, pos)
+			for _, ptr := range c.ptrs[dtype] {
+				ptr.Go.(*ast.StarExpr).X = t.Go
+				ptr.C.Set("%s*", t.C)
+			}
+			delete(c.ptrs, dtype)
+		}
+	}
+
+	// Now that pointer types are completed, we can invoke godefsFields
+	// to rewrite struct definitions.
+	for _, fld := range c.todoFlds {
+		godefsFields(fld)
+	}
+	c.todoFlds = nil
+}
+
+// Type returns a *Type with the same memory layout as
+// dtype when used as the type of a variable or a struct field.
+func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
+	if t, ok := c.m[dtype]; ok {
+		if t.Go == nil {
+			fatalf("%s: type conversion loop at %s", lineno(pos), dtype)
+		}
+		return t
+	}
+
+	// clang won't generate DW_AT_byte_size for pointer types,
+	// so we have to fix it here.
+	if dt, ok := base(dtype).(*dwarf.PtrType); ok && dt.ByteSize == -1 {
+		dt.ByteSize = c.ptrSize
+	}
+
+	t := new(Type)
+	t.Size = dtype.Size() // note: wrong for array of pointers, corrected below
+	t.Align = -1
+	t.C = &TypeRepr{Repr: dtype.Common().Name}
+	c.m[dtype] = t
+
+	switch dt := dtype.(type) {
+	default:
+		fatalf("%s: unexpected type: %s", lineno(pos), dtype)
+
+	case *dwarf.AddrType:
+		if t.Size != c.ptrSize {
+			fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype)
+		}
+		t.Go = c.uintptr
+		t.Align = t.Size
+
+	case *dwarf.ArrayType:
+		if dt.StrideBitSize > 0 {
+			// Cannot represent bit-sized elements in Go.
+			t.Go = c.Opaque(t.Size)
+			break
+		}
+		sub := c.Type(dt.Type, pos)
+		t.Align = sub.Align
+		t.Go = &ast.ArrayType{
+			Len: c.intExpr(dt.Count),
+			Elt: sub.Go,
+		}
+		t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count)
+
+	case *dwarf.BoolType:
+		t.Go = c.bool
+		t.Align = 1
+
+	case *dwarf.CharType:
+		if t.Size != 1 {
+			fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype)
+		}
+		t.Go = c.int8
+		t.Align = 1
+
+	case *dwarf.EnumType:
+		if t.Align = t.Size; t.Align >= c.ptrSize {
+			t.Align = c.ptrSize
+		}
+		t.C.Set("enum " + dt.EnumName)
+		signed := 0
+		t.EnumValues = make(map[string]int64)
+		for _, ev := range dt.Val {
+			t.EnumValues[ev.Name] = ev.Val
+			if ev.Val < 0 {
+				signed = signedDelta
+			}
+		}
+		switch t.Size + int64(signed) {
+		default:
+			fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype)
+		case 1:
+			t.Go = c.uint8
+		case 2:
+			t.Go = c.uint16
+		case 4:
+			t.Go = c.uint32
+		case 8:
+			t.Go = c.uint64
+		case 1 + signedDelta:
+			t.Go = c.int8
+		case 2 + signedDelta:
+			t.Go = c.int16
+		case 4 + signedDelta:
+			t.Go = c.int32
+		case 8 + signedDelta:
+			t.Go = c.int64
+		}
+
+	case *dwarf.FloatType:
+		switch t.Size {
+		default:
+			fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype)
+		case 4:
+			t.Go = c.float32
+		case 8:
+			t.Go = c.float64
+		}
+		if t.Align = t.Size; t.Align >= c.ptrSize {
+			t.Align = c.ptrSize
+		}
+
+	case *dwarf.ComplexType:
+		switch t.Size {
+		default:
+			fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype)
+		case 8:
+			t.Go = c.complex64
+		case 16:
+			t.Go = c.complex128
+		}
+		if t.Align = t.Size; t.Align >= c.ptrSize {
+			t.Align = c.ptrSize
+		}
+
+	case *dwarf.FuncType:
+		// No attempt at translation: would enable calls
+		// directly between worlds, but we need to moderate those.
+		t.Go = c.uintptr
+		t.Align = c.ptrSize
+
+	case *dwarf.IntType:
+		if dt.BitSize > 0 {
+			fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype)
+		}
+		switch t.Size {
+		default:
+			fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype)
+		case 1:
+			t.Go = c.int8
+		case 2:
+			t.Go = c.int16
+		case 4:
+			t.Go = c.int32
+		case 8:
+			t.Go = c.int64
+		}
+		if t.Align = t.Size; t.Align >= c.ptrSize {
+			t.Align = c.ptrSize
+		}
+
+	case *dwarf.PtrType:
+		t.Align = c.ptrSize
+
+		// Translate void* as unsafe.Pointer
+		if _, ok := base(dt.Type).(*dwarf.VoidType); ok {
+			t.Go = c.unsafePointer
+			t.C.Set("void*")
+			break
+		}
+
+		// Placeholder initialization; completed in FinishType.
+		t.Go = &ast.StarExpr{}
+		t.C.Set("<incomplete>*")
+		c.ptrs[dt.Type] = append(c.ptrs[dt.Type], t)
+
+	case *dwarf.QualType:
+		// Ignore qualifier.
+		t = c.Type(dt.Type, pos)
+		c.m[dtype] = t
+		return t
+
+	case *dwarf.StructType:
+		// Convert to Go struct, being careful about alignment.
+		// Have to give it a name to simulate C "struct foo" references.
+		tag := dt.StructName
+		if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible
+			break
+		}
+		if tag == "" {
+			tag = "__" + strconv.Itoa(tagGen)
+			tagGen++
+		} else if t.C.Empty() {
+			t.C.Set(dt.Kind + " " + tag)
+		}
+		name := c.Ident("_Ctype_" + dt.Kind + "_" + tag)
+		t.Go = name // publish before recursive calls
+		goIdent[name.Name] = name
+		if dt.ByteSize < 0 {
+			// Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown),
+			// so execute the basic things that the struct case would do
+			// other than try to determine a Go representation.
+			tt := *t
+			tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
+			tt.Go = c.Ident("struct{}")
+			typedef[name.Name] = &tt
+			break
+		}
+		switch dt.Kind {
+		case "class", "union":
+			t.Go = c.Opaque(t.Size)
+			if t.C.Empty() {
+				t.C.Set("__typeof__(unsigned char[%d])", t.Size)
+			}
+			t.Align = 1 // TODO: should probably base this on field alignment.
+			typedef[name.Name] = t
+		case "struct":
+			g, csyntax, align := c.Struct(dt, pos)
+			if t.C.Empty() {
+				t.C.Set(csyntax)
+			}
+			t.Align = align
+			tt := *t
+			if tag != "" {
+				tt.C = &TypeRepr{"struct %s", []interface{}{tag}}
+			}
+			tt.Go = g
+			typedef[name.Name] = &tt
+		}
+
+	case *dwarf.TypedefType:
+		// Record typedef for printing.
+		if dt.Name == "_GoString_" {
+			// Special C name for Go string type.
+			// Knows string layout used by compilers: pointer plus length,
+			// which rounds up to 2 pointers after alignment.
+			t.Go = c.string
+			t.Size = c.ptrSize * 2
+			t.Align = c.ptrSize
+			break
+		}
+		if dt.Name == "_GoBytes_" {
+			// Special C name for Go []byte type.
+			// Knows slice layout used by compilers: pointer, length, cap.
+			t.Go = c.Ident("[]byte")
+			t.Size = c.ptrSize + 4 + 4
+			t.Align = c.ptrSize
+			break
+		}
+		name := c.Ident("_Ctype_" + dt.Name)
+		goIdent[name.Name] = name
+		sub := c.Type(dt.Type, pos)
+		t.Go = name
+		t.Size = sub.Size
+		t.Align = sub.Align
+		oldType := typedef[name.Name]
+		if oldType == nil {
+			tt := *t
+			tt.Go = sub.Go
+			typedef[name.Name] = &tt
+		}
+
+		// If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
+		// use that as the Go form for this typedef too, so that the typedef will be interchangeable
+		// with the base type.
+		// In -godefs and -cdefs mode, do this for all typedefs.
+		if isStructUnionClass(sub.Go) || *godefs || *cdefs {
+			t.Go = sub.Go
+
+			if isStructUnionClass(sub.Go) {
+				// Use the typedef name for C code.
+				typedef[sub.Go.(*ast.Ident).Name].C = t.C
+			}
+
+			// If we've seen this typedef before, and it
+			// was an anonymous struct/union/class before
+			// too, use the old definition.
+			// TODO: it would be safer to only do this if
+			// we verify that the types are the same.
+			if oldType != nil && isStructUnionClass(oldType.Go) {
+				t.Go = oldType.Go
+			}
+		}
+
+	case *dwarf.UcharType:
+		if t.Size != 1 {
+			fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype)
+		}
+		t.Go = c.uint8
+		t.Align = 1
+
+	case *dwarf.UintType:
+		if dt.BitSize > 0 {
+			fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype)
+		}
+		switch t.Size {
+		default:
+			fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype)
+		case 1:
+			t.Go = c.uint8
+		case 2:
+			t.Go = c.uint16
+		case 4:
+			t.Go = c.uint32
+		case 8:
+			t.Go = c.uint64
+		}
+		if t.Align = t.Size; t.Align >= c.ptrSize {
+			t.Align = c.ptrSize
+		}
+
+	case *dwarf.VoidType:
+		t.Go = c.goVoid
+		t.C.Set("void")
+		t.Align = 1
+	}
+
+	switch dtype.(type) {
+	case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType:
+		s := dtype.Common().Name
+		if s != "" {
+			if ss, ok := dwarfToName[s]; ok {
+				s = ss
+			}
+			s = strings.Join(strings.Split(s, " "), "") // strip spaces
+			name := c.Ident("_Ctype_" + s)
+			tt := *t
+			typedef[name.Name] = &tt
+			if !*godefs && !*cdefs {
+				t.Go = name
+			}
+		}
+	}
+
+	if t.Size <= 0 {
+		// Clang does not record the size of a pointer in its DWARF entry,
+		// so if dtype is an array, the call to dtype.Size at the top of the function
+		// computed the size as the array length * 0 = 0.
+		// The type switch called Type (this function) recursively on the pointer
+		// entry, and the code near the top of the function updated the size to
+		// be correct, so calling dtype.Size again will produce the correct value.
+		t.Size = dtype.Size()
+		if t.Size < 0 {
+			// Unsized types are [0]byte, unless they're typedefs of other types
+			// or structs with tags.
+			// if so, use the name we've already defined.
+			t.Size = 0
+			switch dt := dtype.(type) {
+			case *dwarf.TypedefType:
+				// ok
+			case *dwarf.StructType:
+				if dt.StructName != "" {
+					break
+				}
+				t.Go = c.Opaque(0)
+			default:
+				t.Go = c.Opaque(0)
+			}
+			if t.C.Empty() {
+				t.C.Set("void")
+			}
+			return t
+		}
+	}
+
+	if t.C.Empty() {
+		fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype)
+	}
+
+	return t
+}
+
+// isStructUnionClass reports whether the type described by the Go syntax x
+// is a struct, union, or class with a tag.
+func isStructUnionClass(x ast.Expr) bool {
+	id, ok := x.(*ast.Ident)
+	if !ok {
+		return false
+	}
+	name := id.Name
+	return strings.HasPrefix(name, "_Ctype_struct_") ||
+		strings.HasPrefix(name, "_Ctype_union_") ||
+		strings.HasPrefix(name, "_Ctype_class_")
+}
+
+// FuncArg returns a Go type with the same memory layout as
+// dtype when used as the type of a C function argument.
+func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
+	t := c.Type(dtype, pos)
+	switch dt := dtype.(type) {
+	case *dwarf.ArrayType:
+		// Arrays are passed implicitly as pointers in C.
+		// In Go, we must be explicit.
+		tr := &TypeRepr{}
+		tr.Set("%s*", t.C)
+		return &Type{
+			Size:  c.ptrSize,
+			Align: c.ptrSize,
+			Go:    &ast.StarExpr{X: t.Go},
+			C:     tr,
+		}
+	case *dwarf.TypedefType:
+		// C has much more relaxed rules than Go for
+		// implicit type conversions.  When the parameter
+		// is type T defined as *X, simulate a little of the
+		// laxness of C by making the argument *X instead of T.
+		if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok {
+			// Unless the typedef happens to point to void* since
+			// Go has special rules around using unsafe.Pointer.
+			if _, void := base(ptr.Type).(*dwarf.VoidType); void {
+				break
+			}
+
+			t = c.Type(ptr, pos)
+			if t == nil {
+				return nil
+			}
+
+			// Remember the C spelling, in case the struct
+			// has __attribute__((unavailable)) on it.  See issue 2888.
+			t.Typedef = dt.Name
+		}
+	}
+	return t
+}
+
+// FuncType returns the Go type analogous to dtype.
+// There is no guarantee about matching memory layout.
+func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType {
+	p := make([]*Type, len(dtype.ParamType))
+	gp := make([]*ast.Field, len(dtype.ParamType))
+	for i, f := range dtype.ParamType {
+		// gcc's DWARF generator outputs a single DotDotDotType parameter for
+		// function pointers that specify no parameters (e.g. void
+		// (*__cgo_0)()).  Treat this special case as void.  This case is
+		// invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not
+		// legal).
+		if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 {
+			p, gp = nil, nil
+			break
+		}
+		p[i] = c.FuncArg(f, pos)
+		gp[i] = &ast.Field{Type: p[i].Go}
+	}
+	var r *Type
+	var gr []*ast.Field
+	if _, ok := dtype.ReturnType.(*dwarf.VoidType); ok {
+		gr = []*ast.Field{{Type: c.goVoid}}
+	} else if dtype.ReturnType != nil {
+		r = c.Type(dtype.ReturnType, pos)
+		gr = []*ast.Field{{Type: r.Go}}
+	}
+	return &FuncType{
+		Params: p,
+		Result: r,
+		Go: &ast.FuncType{
+			Params:  &ast.FieldList{List: gp},
+			Results: &ast.FieldList{List: gr},
+		},
+	}
+}
+
+// Identifier
+func (c *typeConv) Ident(s string) *ast.Ident {
+	return ast.NewIdent(s)
+}
+
+// Opaque type of n bytes.
+func (c *typeConv) Opaque(n int64) ast.Expr {
+	return &ast.ArrayType{
+		Len: c.intExpr(n),
+		Elt: c.byte,
+	}
+}
+
+// Expr for integer n.
+func (c *typeConv) intExpr(n int64) ast.Expr {
+	return &ast.BasicLit{
+		Kind:  token.INT,
+		Value: strconv.FormatInt(n, 10),
+	}
+}
+
+// Add padding of given size to fld.
+func (c *typeConv) pad(fld []*ast.Field, size int64) []*ast.Field {
+	n := len(fld)
+	fld = fld[0 : n+1]
+	fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)}
+	return fld
+}
+
+// Struct conversion: return Go and (6g) C syntax for type.
+func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
+	var buf bytes.Buffer
+	buf.WriteString("struct {")
+	fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
+	off := int64(0)
+
+	// Rename struct fields that happen to be named Go keywords into
+	// _{keyword}.  Create a map from C ident -> Go ident.  The Go ident will
+	// be mangled.  Any existing identifier that already has the same name on
+	// the C-side will cause the Go-mangled version to be prefixed with _.
+	// (e.g. in a struct with fields '_type' and 'type', the latter would be
+	// rendered as '__type' in Go).
+	ident := make(map[string]string)
+	used := make(map[string]bool)
+	for _, f := range dt.Field {
+		ident[f.Name] = f.Name
+		used[f.Name] = true
+	}
+
+	if !*godefs && !*cdefs {
+		for cid, goid := range ident {
+			if token.Lookup(goid).IsKeyword() {
+				// Avoid keyword
+				goid = "_" + goid
+
+				// Also avoid existing fields
+				for _, exist := used[goid]; exist; _, exist = used[goid] {
+					goid = "_" + goid
+				}
+
+				used[goid] = true
+				ident[cid] = goid
+			}
+		}
+	}
+
+	anon := 0
+	for _, f := range dt.Field {
+		if f.ByteOffset > off {
+			fld = c.pad(fld, f.ByteOffset-off)
+			off = f.ByteOffset
+		}
+		t := c.Type(f.Type, pos)
+		tgo := t.Go
+		size := t.Size
+		talign := t.Align
+		if f.BitSize > 0 {
+			if f.BitSize%8 != 0 {
+				continue
+			}
+			size = f.BitSize / 8
+			name := tgo.(*ast.Ident).String()
+			if strings.HasPrefix(name, "int") {
+				name = "int"
+			} else {
+				name = "uint"
+			}
+			tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize))
+			talign = size
+		}
+
+		if talign > 0 && f.ByteOffset%talign != 0 {
+			// Drop misaligned fields, the same way we drop integer bit fields.
+			// The goal is to make available what can be made available.
+			// Otherwise one bad and unneeded field in an otherwise okay struct
+			// makes the whole program not compile. Much of the time these
+			// structs are in system headers that cannot be corrected.
+			continue
+		}
+		n := len(fld)
+		fld = fld[0 : n+1]
+		name := f.Name
+		if name == "" {
+			name = fmt.Sprintf("anon%d", anon)
+			anon++
+			ident[name] = name
+		}
+		fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo}
+		off += size
+		buf.WriteString(t.C.String())
+		buf.WriteString(" ")
+		buf.WriteString(name)
+		buf.WriteString("; ")
+		if talign > align {
+			align = talign
+		}
+	}
+	if off < dt.ByteSize {
+		fld = c.pad(fld, dt.ByteSize-off)
+		off = dt.ByteSize
+	}
+	if off != dt.ByteSize {
+		fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize)
+	}
+	buf.WriteString("}")
+	csyntax = buf.String()
+
+	if *godefs || *cdefs {
+		c.todoFlds = append(c.todoFlds, fld)
+	}
+	expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
+	return
+}
+
+func upper(s string) string {
+	if s == "" {
+		return ""
+	}
+	r, size := utf8.DecodeRuneInString(s)
+	if r == '_' {
+		return "X" + s
+	}
+	return string(unicode.ToUpper(r)) + s[size:]
+}
+
+// godefsFields rewrites field names for use in Go or C definitions.
+// It strips leading common prefixes (like tv_ in tv_sec, tv_usec)
+// converts names to upper case, and rewrites _ into Pad_godefs_n,
+// so that all fields are exported.
+func godefsFields(fld []*ast.Field) {
+	prefix := fieldPrefix(fld)
+	npad := 0
+	for _, f := range fld {
+		for _, n := range f.Names {
+			if n.Name != prefix {
+				n.Name = strings.TrimPrefix(n.Name, prefix)
+			}
+			if n.Name == "_" {
+				// Use exported name instead.
+				n.Name = "Pad_cgo_" + strconv.Itoa(npad)
+				npad++
+			}
+			if !*cdefs {
+				n.Name = upper(n.Name)
+			}
+		}
+		p := &f.Type
+		t := *p
+		if star, ok := t.(*ast.StarExpr); ok {
+			star = &ast.StarExpr{X: star.X}
+			*p = star
+			p = &star.X
+			t = *p
+		}
+		if id, ok := t.(*ast.Ident); ok {
+			if id.Name == "unsafe.Pointer" {
+				*p = ast.NewIdent("*byte")
+			}
+		}
+	}
+}
+
+// fieldPrefix returns the prefix that should be removed from all the
+// field names when generating the C or Go code.  For generated
+// C, we leave the names as is (tv_sec, tv_usec), since that's what
+// people are used to seeing in C.  For generated Go code, such as
+// package syscall's data structures, we drop a common prefix
+// (so sec, usec, which will get turned into Sec, Usec for exporting).
+func fieldPrefix(fld []*ast.Field) string {
+	if *cdefs {
+		return ""
+	}
+	prefix := ""
+	for _, f := range fld {
+		for _, n := range f.Names {
+			// Ignore field names that don't have the prefix we're
+			// looking for.  It is common in C headers to have fields
+			// named, say, _pad in an otherwise prefixed header.
+			// If the struct has 3 fields tv_sec, tv_usec, _pad1, then we
+			// still want to remove the tv_ prefix.
+			// The check for "orig_" here handles orig_eax in the
+			// x86 ptrace register sets, which otherwise have all fields
+			// with reg_ prefixes.
+			if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") {
+				continue
+			}
+			i := strings.Index(n.Name, "_")
+			if i < 0 {
+				continue
+			}
+			if prefix == "" {
+				prefix = n.Name[:i+1]
+			} else if prefix != n.Name[:i+1] {
+				return ""
+			}
+		}
+	}
+	return prefix
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/cgo/godefs.go b/third_party/gofrontend/libgo/go/cmd/cgo/godefs.go
new file mode 100644
index 0000000..ce5ac27
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/cgo/godefs.go
@@ -0,0 +1,294 @@
+// Copyright 2011 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 (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/printer"
+	"go/token"
+	"os"
+	"strings"
+)
+
+// godefs returns the output for -godefs mode.
+func (p *Package) godefs(f *File, srcfile string) string {
+	var buf bytes.Buffer
+
+	fmt.Fprintf(&buf, "// Created by cgo -godefs - DO NOT EDIT\n")
+	fmt.Fprintf(&buf, "// %s\n", strings.Join(os.Args, " "))
+	fmt.Fprintf(&buf, "\n")
+
+	override := make(map[string]string)
+
+	// Allow source file to specify override mappings.
+	// For example, the socket data structures refer
+	// to in_addr and in_addr6 structs but we want to be
+	// able to treat them as byte arrays, so the godefs
+	// inputs in package syscall say
+	//
+	//	// +godefs map struct_in_addr [4]byte
+	//	// +godefs map struct_in_addr6 [16]byte
+	//
+	for _, g := range f.Comments {
+		for _, c := range g.List {
+			i := strings.Index(c.Text, "+godefs map")
+			if i < 0 {
+				continue
+			}
+			s := strings.TrimSpace(c.Text[i+len("+godefs map"):])
+			i = strings.Index(s, " ")
+			if i < 0 {
+				fmt.Fprintf(os.Stderr, "invalid +godefs map comment: %s\n", c.Text)
+				continue
+			}
+			override["_Ctype_"+strings.TrimSpace(s[:i])] = strings.TrimSpace(s[i:])
+		}
+	}
+	for _, n := range f.Name {
+		if s := override[n.Go]; s != "" {
+			override[n.Mangle] = s
+		}
+	}
+
+	// Otherwise, if the source file says type T C.whatever,
+	// use "T" as the mangling of C.whatever,
+	// except in the definition (handled at end of function).
+	refName := make(map[*ast.Expr]*Name)
+	for _, r := range f.Ref {
+		refName[r.Expr] = r.Name
+	}
+	for _, d := range f.AST.Decls {
+		d, ok := d.(*ast.GenDecl)
+		if !ok || d.Tok != token.TYPE {
+			continue
+		}
+		for _, s := range d.Specs {
+			s := s.(*ast.TypeSpec)
+			n := refName[&s.Type]
+			if n != nil && n.Mangle != "" {
+				override[n.Mangle] = s.Name.Name
+			}
+		}
+	}
+
+	// Extend overrides using typedefs:
+	// If we know that C.xxx should format as T
+	// and xxx is a typedef for yyy, make C.yyy format as T.
+	for typ, def := range typedef {
+		if new := override[typ]; new != "" {
+			if id, ok := def.Go.(*ast.Ident); ok {
+				override[id.Name] = new
+			}
+		}
+	}
+
+	// Apply overrides.
+	for old, new := range override {
+		if id := goIdent[old]; id != nil {
+			id.Name = new
+		}
+	}
+
+	// Any names still using the _C syntax are not going to compile,
+	// although in general we don't know whether they all made it
+	// into the file, so we can't warn here.
+	//
+	// The most common case is union types, which begin with
+	// _Ctype_union and for which typedef[name] is a Go byte
+	// array of the appropriate size (such as [4]byte).
+	// Substitute those union types with byte arrays.
+	for name, id := range goIdent {
+		if id.Name == name && strings.Contains(name, "_Ctype_union") {
+			if def := typedef[name]; def != nil {
+				id.Name = gofmt(def)
+			}
+		}
+	}
+
+	conf.Fprint(&buf, fset, f.AST)
+
+	return buf.String()
+}
+
+// cdefs returns the output for -cdefs mode.
+// The easiest way to do this is to translate the godefs Go to C.
+func (p *Package) cdefs(f *File, srcfile string) string {
+	godefsOutput := p.godefs(f, srcfile)
+
+	lines := strings.Split(godefsOutput, "\n")
+	lines[0] = "// Created by cgo -cdefs - DO NOT EDIT"
+
+	for i, line := range lines {
+		lines[i] = strings.TrimSpace(line)
+	}
+
+	var out bytes.Buffer
+	printf := func(format string, args ...interface{}) { fmt.Fprintf(&out, format, args...) }
+
+	didTypedef := false
+	for i := 0; i < len(lines); i++ {
+		line := lines[i]
+
+		// Delete
+		//	package x
+		if strings.HasPrefix(line, "package ") {
+			continue
+		}
+
+		// Convert
+		//	const (
+		//		A = 1
+		//		B = 2
+		//	)
+		//
+		// to
+		//
+		//	enum {
+		//		A = 1,
+		//		B = 2,
+		//	};
+		if line == "const (" {
+			printf("enum {\n")
+			for i++; i < len(lines) && lines[i] != ")"; i++ {
+				line = lines[i]
+				if line != "" {
+					printf("\t%s,", line)
+				}
+				printf("\n")
+			}
+			printf("};\n")
+			continue
+		}
+
+		// Convert
+		//	const A = 1
+		// to
+		//	enum { A = 1 };
+		if strings.HasPrefix(line, "const ") {
+			printf("enum { %s };\n", line[len("const "):])
+			continue
+		}
+
+		// On first type definition, typedef all the structs
+		// in case there are dependencies between them.
+		if !didTypedef && strings.HasPrefix(line, "type ") {
+			didTypedef = true
+			for _, line := range lines {
+				line = strings.TrimSpace(line)
+				if strings.HasPrefix(line, "type ") && strings.HasSuffix(line, " struct {") {
+					s := strings.TrimSuffix(strings.TrimPrefix(line, "type "), " struct {")
+					printf("typedef struct %s %s;\n", s, s)
+				}
+			}
+			printf("\n")
+			printf("#pragma pack on\n")
+			printf("\n")
+		}
+
+		// Convert
+		//	type T struct {
+		//		X int64
+		//		Y *int32
+		//		Z [4]byte
+		//	}
+		//
+		// to
+		//
+		//	struct T {
+		//		int64 X;
+		//		int32 *Y;
+		//		byte Z[4];
+		//	}
+		if strings.HasPrefix(line, "type ") && strings.HasSuffix(line, " struct {") {
+			if len(lines) > i+1 && lines[i+1] == "}" {
+				// do not output empty struct
+				i++
+				continue
+			}
+			s := line[len("type ") : len(line)-len(" struct {")]
+			printf("struct %s {\n", s)
+			for i++; i < len(lines) && lines[i] != "}"; i++ {
+				line := lines[i]
+				if line != "" {
+					f := strings.Fields(line)
+					if len(f) != 2 {
+						fmt.Fprintf(os.Stderr, "cgo: cannot parse struct field: %s\n", line)
+						nerrors++
+						continue
+					}
+					printf("\t%s;", cdecl(f[0], f[1]))
+				}
+				printf("\n")
+			}
+			printf("};\n")
+			continue
+		}
+
+		// Convert
+		//	type T int
+		// to
+		//	typedef int T;
+		if strings.HasPrefix(line, "type ") {
+			f := strings.Fields(line[len("type "):])
+			if len(f) != 2 {
+				fmt.Fprintf(os.Stderr, "cgo: cannot parse type definition: %s\n", line)
+				nerrors++
+				continue
+			}
+			printf("typedef\t%s;\n", cdecl(f[0], f[1]))
+			continue
+		}
+
+		printf("%s\n", line)
+	}
+
+	if didTypedef {
+		printf("\n")
+		printf("#pragma pack off\n")
+	}
+
+	return out.String()
+}
+
+// cdecl returns the C declaration for the given Go name and type.
+// It only handles the specific cases necessary for converting godefs output.
+func cdecl(name, typ string) string {
+	// X *[0]byte -> X *void
+	if strings.HasPrefix(typ, "*[0]") {
+		typ = "*void"
+	}
+	// X [4]byte -> X[4] byte
+	for strings.HasPrefix(typ, "[") {
+		i := strings.Index(typ, "]") + 1
+		name = name + typ[:i]
+		typ = typ[i:]
+	}
+	// X *byte -> *X byte
+	for strings.HasPrefix(typ, "*") {
+		name = "*" + name
+		typ = typ[1:]
+	}
+	// X T -> T X
+	// Handle the special case: 'unsafe.Pointer' is 'void *'
+	if typ == "unsafe.Pointer" {
+		typ = "void"
+		name = "*" + name
+	}
+	return typ + "\t" + name
+}
+
+var gofmtBuf bytes.Buffer
+
+// gofmt returns the gofmt-formatted string for an AST node.
+func gofmt(n interface{}) string {
+	gofmtBuf.Reset()
+	err := printer.Fprint(&gofmtBuf, fset, n)
+	if err != nil {
+		return "<" + err.Error() + ">"
+	}
+	return gofmtBuf.String()
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/cgo/main.go b/third_party/gofrontend/libgo/go/cmd/cgo/main.go
new file mode 100644
index 0000000..ea4b9c2
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/cgo/main.go
@@ -0,0 +1,360 @@
+// 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.
+
+// Cgo; see gmp.go for an overview.
+
+// TODO(rsc):
+//	Emit correct line number annotations.
+//	Make 6g understand the annotations.
+
+package main
+
+import (
+	"crypto/md5"
+	"flag"
+	"fmt"
+	"go/ast"
+	"go/printer"
+	"go/token"
+	"io"
+	"os"
+	"path/filepath"
+	"reflect"
+	"runtime"
+	"sort"
+	"strings"
+)
+
+// A Package collects information about the package we're going to write.
+type Package struct {
+	PackageName string // name of package
+	PackagePath string
+	PtrSize     int64
+	IntSize     int64
+	GccOptions  []string
+	CgoFlags    map[string][]string // #cgo flags (CFLAGS, LDFLAGS)
+	Written     map[string]bool
+	Name        map[string]*Name // accumulated Name from Files
+	ExpFunc     []*ExpFunc       // accumulated ExpFunc from Files
+	Decl        []ast.Decl
+	GoFiles     []string // list of Go files
+	GccFiles    []string // list of gcc output files
+	Preamble    string   // collected preamble for _cgo_export.h
+}
+
+// A File collects information about a single Go input file.
+type File struct {
+	AST      *ast.File           // parsed AST
+	Comments []*ast.CommentGroup // comments from file
+	Package  string              // Package name
+	Preamble string              // C preamble (doc comment on import "C")
+	Ref      []*Ref              // all references to C.xxx in AST
+	ExpFunc  []*ExpFunc          // exported functions for this file
+	Name     map[string]*Name    // map from Go name to Name
+}
+
+func nameKeys(m map[string]*Name) []string {
+	var ks []string
+	for k := range m {
+		ks = append(ks, k)
+	}
+	sort.Strings(ks)
+	return ks
+}
+
+// A Ref refers to an expression of the form C.xxx in the AST.
+type Ref struct {
+	Name    *Name
+	Expr    *ast.Expr
+	Context string // "type", "expr", "call", or "call2"
+}
+
+func (r *Ref) Pos() token.Pos {
+	return (*r.Expr).Pos()
+}
+
+// A Name collects information about C.xxx.
+type Name struct {
+	Go       string // name used in Go referring to package C
+	Mangle   string // name used in generated Go
+	C        string // name used in C
+	Define   string // #define expansion
+	Kind     string // "const", "type", "var", "fpvar", "func", "not-type"
+	Type     *Type  // the type of xxx
+	FuncType *FuncType
+	AddError bool
+	Const    string // constant definition
+}
+
+// IsVar returns true if Kind is either "var" or "fpvar"
+func (n *Name) IsVar() bool {
+	return n.Kind == "var" || n.Kind == "fpvar"
+}
+
+// A ExpFunc is an exported function, callable from C.
+// Such functions are identified in the Go input file
+// by doc comments containing the line //export ExpName
+type ExpFunc struct {
+	Func    *ast.FuncDecl
+	ExpName string // name to use from C
+}
+
+// A TypeRepr contains the string representation of a type.
+type TypeRepr struct {
+	Repr       string
+	FormatArgs []interface{}
+}
+
+// A Type collects information about a type in both the C and Go worlds.
+type Type struct {
+	Size       int64
+	Align      int64
+	C          *TypeRepr
+	Go         ast.Expr
+	EnumValues map[string]int64
+	Typedef    string
+}
+
+// A FuncType collects information about a function type in both the C and Go worlds.
+type FuncType struct {
+	Params []*Type
+	Result *Type
+	Go     *ast.FuncType
+}
+
+func usage() {
+	fmt.Fprint(os.Stderr, "usage: cgo -- [compiler options] file.go ...\n")
+	flag.PrintDefaults()
+	os.Exit(2)
+}
+
+var ptrSizeMap = map[string]int64{
+	"386":   4,
+	"amd64": 8,
+	"arm":   4,
+	"ppc64": 8,
+	"ppc64le": 8,
+	"s390x": 8,
+}
+
+var intSizeMap = map[string]int64{
+	"386":   4,
+	"amd64": 8,
+	"arm":   4,
+	"ppc64": 8,
+	"ppc64le": 8,
+	"s390x": 8,
+}
+
+var cPrefix string
+
+var fset = token.NewFileSet()
+
+var dynobj = flag.String("dynimport", "", "if non-empty, print dynamic import data for that file")
+var dynout = flag.String("dynout", "", "write -dynobj output to this file")
+var dynlinker = flag.Bool("dynlinker", false, "record dynamic linker information in dynimport mode")
+
+// These flags are for bootstrapping a new Go implementation,
+// to generate Go and C headers that match the data layout and
+// constant values used in the host's C libraries and system calls.
+var godefs = flag.Bool("godefs", false, "for bootstrap: write Go definitions for C file to standard output")
+var cdefs = flag.Bool("cdefs", false, "for bootstrap: write C definitions for C file to standard output")
+var objDir = flag.String("objdir", "", "object directory")
+
+var gccgo = flag.Bool("gccgo", false, "generate files for use with gccgo")
+var gccgoprefix = flag.String("gccgoprefix", "", "-fgo-prefix option used with gccgo")
+var gccgopkgpath = flag.String("gccgopkgpath", "", "-fgo-pkgpath option used with gccgo")
+var importRuntimeCgo = flag.Bool("import_runtime_cgo", true, "import runtime/cgo in generated code")
+var importSyscall = flag.Bool("import_syscall", true, "import syscall in generated code")
+var goarch, goos string
+
+func main() {
+	flag.Usage = usage
+	flag.Parse()
+
+	if *dynobj != "" {
+		// cgo -dynimport is essentially a separate helper command
+		// built into the cgo binary.  It scans a gcc-produced executable
+		// and dumps information about the imported symbols and the
+		// imported libraries.  The 'go build' rules for cgo prepare an
+		// appropriate executable and then use its import information
+		// instead of needing to make the linkers duplicate all the
+		// specialized knowledge gcc has about where to look for imported
+		// symbols and which ones to use.
+		dynimport(*dynobj)
+		return
+	}
+
+	if *godefs && *cdefs {
+		fmt.Fprintf(os.Stderr, "cgo: cannot use -cdefs and -godefs together\n")
+		os.Exit(2)
+	}
+
+	if *godefs || *cdefs {
+		// Generating definitions pulled from header files,
+		// to be checked into Go repositories.
+		// Line numbers are just noise.
+		conf.Mode &^= printer.SourcePos
+	}
+
+	args := flag.Args()
+	if len(args) < 1 {
+		usage()
+	}
+
+	// Find first arg that looks like a go file and assume everything before
+	// that are options to pass to gcc.
+	var i int
+	for i = len(args); i > 0; i-- {
+		if !strings.HasSuffix(args[i-1], ".go") {
+			break
+		}
+	}
+	if i == len(args) {
+		usage()
+	}
+
+	goFiles := args[i:]
+
+	p := newPackage(args[:i])
+
+	// Record CGO_LDFLAGS from the environment for external linking.
+	if ldflags := os.Getenv("CGO_LDFLAGS"); ldflags != "" {
+		args, err := splitQuoted(ldflags)
+		if err != nil {
+			fatalf("bad CGO_LDFLAGS: %q (%s)", ldflags, err)
+		}
+		p.addToFlag("LDFLAGS", args)
+	}
+
+	// Need a unique prefix for the global C symbols that
+	// we use to coordinate between gcc and ourselves.
+	// We already put _cgo_ at the beginning, so the main
+	// concern is other cgo wrappers for the same functions.
+	// Use the beginning of the md5 of the input to disambiguate.
+	h := md5.New()
+	for _, input := range goFiles {
+		f, err := os.Open(input)
+		if err != nil {
+			fatalf("%s", err)
+		}
+		io.Copy(h, f)
+		f.Close()
+	}
+	cPrefix = fmt.Sprintf("_%x", h.Sum(nil)[0:6])
+
+	fs := make([]*File, len(goFiles))
+	for i, input := range goFiles {
+		f := new(File)
+		f.ReadGo(input)
+		f.DiscardCgoDirectives()
+		fs[i] = f
+	}
+
+	if *objDir == "" {
+		// make sure that _obj directory exists, so that we can write
+		// all the output files there.
+		os.Mkdir("_obj", 0777)
+		*objDir = "_obj"
+	}
+	*objDir += string(filepath.Separator)
+
+	for i, input := range goFiles {
+		f := fs[i]
+		p.Translate(f)
+		for _, cref := range f.Ref {
+			switch cref.Context {
+			case "call", "call2":
+				if cref.Name.Kind != "type" {
+					break
+				}
+				*cref.Expr = cref.Name.Type.Go
+			}
+		}
+		if nerrors > 0 {
+			os.Exit(2)
+		}
+		pkg := f.Package
+		if dir := os.Getenv("CGOPKGPATH"); dir != "" {
+			pkg = filepath.Join(dir, pkg)
+		}
+		p.PackagePath = pkg
+		p.Record(f)
+		if *godefs {
+			os.Stdout.WriteString(p.godefs(f, input))
+		} else if *cdefs {
+			os.Stdout.WriteString(p.cdefs(f, input))
+		} else {
+			p.writeOutput(f, input)
+		}
+	}
+
+	if !*godefs && !*cdefs {
+		p.writeDefs()
+	}
+	if nerrors > 0 {
+		os.Exit(2)
+	}
+}
+
+// newPackage returns a new Package that will invoke
+// gcc with the additional arguments specified in args.
+func newPackage(args []string) *Package {
+	goarch = runtime.GOARCH
+	if s := os.Getenv("GOARCH"); s != "" {
+		goarch = s
+	}
+	goos = runtime.GOOS
+	if s := os.Getenv("GOOS"); s != "" {
+		goos = s
+	}
+	ptrSize := ptrSizeMap[goarch]
+	if ptrSize == 0 {
+		fatalf("unknown ptrSize for $GOARCH %q", goarch)
+	}
+	intSize := intSizeMap[goarch]
+	if intSize == 0 {
+		fatalf("unknown intSize for $GOARCH %q", goarch)
+	}
+
+	// Reset locale variables so gcc emits English errors [sic].
+	os.Setenv("LANG", "en_US.UTF-8")
+	os.Setenv("LC_ALL", "C")
+
+	p := &Package{
+		PtrSize:  ptrSize,
+		IntSize:  intSize,
+		CgoFlags: make(map[string][]string),
+		Written:  make(map[string]bool),
+	}
+	p.addToFlag("CFLAGS", args)
+	return p
+}
+
+// Record what needs to be recorded about f.
+func (p *Package) Record(f *File) {
+	if p.PackageName == "" {
+		p.PackageName = f.Package
+	} else if p.PackageName != f.Package {
+		error_(token.NoPos, "inconsistent package names: %s, %s", p.PackageName, f.Package)
+	}
+
+	if p.Name == nil {
+		p.Name = f.Name
+	} else {
+		for k, v := range f.Name {
+			if p.Name[k] == nil {
+				p.Name[k] = v
+			} else if !reflect.DeepEqual(p.Name[k], v) {
+				error_(token.NoPos, "inconsistent definitions for C.%s", fixGo(k))
+			}
+		}
+	}
+
+	if f.ExpFunc != nil {
+		p.ExpFunc = append(p.ExpFunc, f.ExpFunc...)
+		p.Preamble += "\n" + f.Preamble
+	}
+	p.Decl = append(p.Decl, f.AST.Decls...)
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/cgo/out.go b/third_party/gofrontend/libgo/go/cmd/cgo/out.go
new file mode 100644
index 0000000..76c7247
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/cgo/out.go
@@ -0,0 +1,1299 @@
+// 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 main
+
+import (
+	"bytes"
+	"debug/elf"
+	"debug/macho"
+	"debug/pe"
+	"fmt"
+	"go/ast"
+	"go/printer"
+	"go/token"
+	"os"
+	"sort"
+	"strings"
+)
+
+var conf = printer.Config{Mode: printer.SourcePos, Tabwidth: 8}
+
+// writeDefs creates output files to be compiled by 6g, 6c, and gcc.
+// (The comments here say 6g and 6c but the code applies to the 8 and 5 tools too.)
+func (p *Package) writeDefs() {
+	fgo2 := creat(*objDir + "_cgo_gotypes.go")
+	fc := creat(*objDir + "_cgo_defun.c")
+	fm := creat(*objDir + "_cgo_main.c")
+
+	var gccgoInit bytes.Buffer
+
+	fflg := creat(*objDir + "_cgo_flags")
+	for k, v := range p.CgoFlags {
+		fmt.Fprintf(fflg, "_CGO_%s=%s\n", k, strings.Join(v, " "))
+		if k == "LDFLAGS" && !*gccgo {
+			for _, arg := range v {
+				fmt.Fprintf(fc, "#pragma cgo_ldflag %q\n", arg)
+			}
+		}
+	}
+	fflg.Close()
+
+	// Write C main file for using gcc to resolve imports.
+	fmt.Fprintf(fm, "int main() { return 0; }\n")
+	if *importRuntimeCgo {
+		fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int), void *a, int c) { }\n")
+	} else {
+		// If we're not importing runtime/cgo, we *are* runtime/cgo,
+		// which provides crosscall2.  We just need a prototype.
+		fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int), void *a, int c);\n")
+	}
+	fmt.Fprintf(fm, "void _cgo_allocate(void *a, int c) { }\n")
+	fmt.Fprintf(fm, "void _cgo_panic(void *a, int c) { }\n")
+
+	// Write second Go output: definitions of _C_xxx.
+	// In a separate file so that the import of "unsafe" does not
+	// pollute the original file.
+	fmt.Fprintf(fgo2, "// Created by cgo - DO NOT EDIT\n\n")
+	fmt.Fprintf(fgo2, "package %s\n\n", p.PackageName)
+	fmt.Fprintf(fgo2, "import \"unsafe\"\n\n")
+	if *importSyscall {
+		fmt.Fprintf(fgo2, "import \"syscall\"\n\n")
+	}
+	if !*gccgo && *importRuntimeCgo {
+		fmt.Fprintf(fgo2, "import _ \"runtime/cgo\"\n\n")
+	}
+	fmt.Fprintf(fgo2, "type _ unsafe.Pointer\n\n")
+	if *importSyscall {
+		fmt.Fprintf(fgo2, "func _Cerrno(dst *error, x int32) { *dst = syscall.Errno(x) }\n")
+	}
+
+	typedefNames := make([]string, 0, len(typedef))
+	for name := range typedef {
+		typedefNames = append(typedefNames, name)
+	}
+	sort.Strings(typedefNames)
+	for _, name := range typedefNames {
+		def := typedef[name]
+		fmt.Fprintf(fgo2, "type %s ", name)
+		conf.Fprint(fgo2, fset, def.Go)
+		fmt.Fprintf(fgo2, "\n\n")
+	}
+	if *gccgo {
+		fmt.Fprintf(fgo2, "type _Ctype_void byte\n")
+	} else {
+		fmt.Fprintf(fgo2, "type _Ctype_void [0]byte\n")
+	}
+
+	if *gccgo {
+		fmt.Fprintf(fc, p.cPrologGccgo())
+	} else {
+		fmt.Fprintf(fc, cProlog)
+	}
+
+	gccgoSymbolPrefix := p.gccgoSymbolPrefix()
+
+	cVars := make(map[string]bool)
+	for _, key := range nameKeys(p.Name) {
+		n := p.Name[key]
+		if !n.IsVar() {
+			continue
+		}
+
+		if !cVars[n.C] {
+			fmt.Fprintf(fm, "extern char %s[];\n", n.C)
+			fmt.Fprintf(fm, "void *_cgohack_%s = %s;\n\n", n.C, n.C)
+
+			if !*gccgo {
+				fmt.Fprintf(fc, "#pragma cgo_import_static %s\n", n.C)
+			}
+
+			fmt.Fprintf(fc, "extern byte *%s;\n", n.C)
+
+			cVars[n.C] = true
+		}
+		var amp string
+		var node ast.Node
+		if n.Kind == "var" {
+			amp = "&"
+			node = &ast.StarExpr{X: n.Type.Go}
+		} else if n.Kind == "fpvar" {
+			node = n.Type.Go
+			if *gccgo {
+				amp = "&"
+			}
+		} else {
+			panic(fmt.Errorf("invalid var kind %q", n.Kind))
+		}
+		if *gccgo {
+			fmt.Fprintf(fc, `extern void *%s __asm__("%s.%s");`, n.Mangle, gccgoSymbolPrefix, n.Mangle)
+			fmt.Fprintf(&gccgoInit, "\t%s = %s%s;\n", n.Mangle, amp, n.C)
+		} else {
+			fmt.Fprintf(fc, "void *·%s = %s%s;\n", n.Mangle, amp, n.C)
+		}
+		fmt.Fprintf(fc, "\n")
+
+		fmt.Fprintf(fgo2, "var %s ", n.Mangle)
+		conf.Fprint(fgo2, fset, node)
+		fmt.Fprintf(fgo2, "\n")
+	}
+	fmt.Fprintf(fc, "\n")
+
+	for _, key := range nameKeys(p.Name) {
+		n := p.Name[key]
+		if n.Const != "" {
+			fmt.Fprintf(fgo2, "const _Cconst_%s = %s\n", n.Go, n.Const)
+		}
+	}
+	fmt.Fprintf(fgo2, "\n")
+
+	for _, key := range nameKeys(p.Name) {
+		n := p.Name[key]
+		if n.FuncType != nil {
+			p.writeDefsFunc(fc, fgo2, n)
+		}
+	}
+
+	if *gccgo {
+		p.writeGccgoExports(fgo2, fc, fm)
+	} else {
+		p.writeExports(fgo2, fc, fm)
+	}
+
+	init := gccgoInit.String()
+	if init != "" {
+		fmt.Fprintln(fc, "static void init(void) __attribute__ ((constructor));")
+		fmt.Fprintln(fc, "static void init(void) {")
+		fmt.Fprint(fc, init)
+		fmt.Fprintln(fc, "}")
+	}
+
+	fgo2.Close()
+	fc.Close()
+}
+
+func dynimport(obj string) {
+	stdout := os.Stdout
+	if *dynout != "" {
+		f, err := os.Create(*dynout)
+		if err != nil {
+			fatalf("%s", err)
+		}
+		stdout = f
+	}
+
+	if f, err := elf.Open(obj); err == nil {
+		if *dynlinker {
+			// Emit the cgo_dynamic_linker line.
+			if sec := f.Section(".interp"); sec != nil {
+				if data, err := sec.Data(); err == nil && len(data) > 1 {
+					// skip trailing \0 in data
+					fmt.Fprintf(stdout, "#pragma cgo_dynamic_linker %q\n", string(data[:len(data)-1]))
+				}
+			}
+		}
+		sym, err := f.ImportedSymbols()
+		if err != nil {
+			fatalf("cannot load imported symbols from ELF file %s: %v", obj, err)
+		}
+		for _, s := range sym {
+			targ := s.Name
+			if s.Version != "" {
+				targ += "#" + s.Version
+			}
+			fmt.Fprintf(stdout, "#pragma cgo_import_dynamic %s %s %q\n", s.Name, targ, s.Library)
+		}
+		lib, err := f.ImportedLibraries()
+		if err != nil {
+			fatalf("cannot load imported libraries from ELF file %s: %v", obj, err)
+		}
+		for _, l := range lib {
+			fmt.Fprintf(stdout, "#pragma cgo_import_dynamic _ _ %q\n", l)
+		}
+		return
+	}
+
+	if f, err := macho.Open(obj); err == nil {
+		sym, err := f.ImportedSymbols()
+		if err != nil {
+			fatalf("cannot load imported symbols from Mach-O file %s: %v", obj, err)
+		}
+		for _, s := range sym {
+			if len(s) > 0 && s[0] == '_' {
+				s = s[1:]
+			}
+			fmt.Fprintf(stdout, "#pragma cgo_import_dynamic %s %s %q\n", s, s, "")
+		}
+		lib, err := f.ImportedLibraries()
+		if err != nil {
+			fatalf("cannot load imported libraries from Mach-O file %s: %v", obj, err)
+		}
+		for _, l := range lib {
+			fmt.Fprintf(stdout, "#pragma cgo_import_dynamic _ _ %q\n", l)
+		}
+		return
+	}
+
+	if f, err := pe.Open(obj); err == nil {
+		sym, err := f.ImportedSymbols()
+		if err != nil {
+			fatalf("cannot load imported symbols from PE file %s: %v", obj, err)
+		}
+		for _, s := range sym {
+			ss := strings.Split(s, ":")
+			name := strings.Split(ss[0], "@")[0]
+			fmt.Fprintf(stdout, "#pragma cgo_import_dynamic %s %s %q\n", name, ss[0], strings.ToLower(ss[1]))
+		}
+		return
+	}
+
+	fatalf("cannot parse %s as ELF, Mach-O or PE", obj)
+}
+
+// Construct a gcc struct matching the 6c argument frame.
+// Assumes that in gcc, char is 1 byte, short 2 bytes, int 4 bytes, long long 8 bytes.
+// These assumptions are checked by the gccProlog.
+// Also assumes that 6c convention is to word-align the
+// input and output parameters.
+func (p *Package) structType(n *Name) (string, int64) {
+	var buf bytes.Buffer
+	fmt.Fprint(&buf, "struct {\n")
+	off := int64(0)
+	for i, t := range n.FuncType.Params {
+		if off%t.Align != 0 {
+			pad := t.Align - off%t.Align
+			fmt.Fprintf(&buf, "\t\tchar __pad%d[%d];\n", off, pad)
+			off += pad
+		}
+		c := t.Typedef
+		if c == "" {
+			c = t.C.String()
+		}
+		fmt.Fprintf(&buf, "\t\t%s p%d;\n", c, i)
+		off += t.Size
+	}
+	if off%p.PtrSize != 0 {
+		pad := p.PtrSize - off%p.PtrSize
+		fmt.Fprintf(&buf, "\t\tchar __pad%d[%d];\n", off, pad)
+		off += pad
+	}
+	if t := n.FuncType.Result; t != nil {
+		if off%t.Align != 0 {
+			pad := t.Align - off%t.Align
+			fmt.Fprintf(&buf, "\t\tchar __pad%d[%d];\n", off, pad)
+			off += pad
+		}
+		qual := ""
+		if c := t.C.String(); c[len(c)-1] == '*' {
+			qual = "const "
+		}
+		fmt.Fprintf(&buf, "\t\t%s%s r;\n", qual, t.C)
+		off += t.Size
+	}
+	if off%p.PtrSize != 0 {
+		pad := p.PtrSize - off%p.PtrSize
+		fmt.Fprintf(&buf, "\t\tchar __pad%d[%d];\n", off, pad)
+		off += pad
+	}
+	if n.AddError {
+		fmt.Fprint(&buf, "\t\tint e[2*sizeof(void *)/sizeof(int)]; /* error */\n")
+		off += 2 * p.PtrSize
+	}
+	if off == 0 {
+		fmt.Fprintf(&buf, "\t\tchar unused;\n") // avoid empty struct
+	}
+	fmt.Fprintf(&buf, "\t}")
+	return buf.String(), off
+}
+
+func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
+	name := n.Go
+	gtype := n.FuncType.Go
+	void := gtype.Results == nil || len(gtype.Results.List) == 0
+	if n.AddError {
+		// Add "error" to return type list.
+		// Type list is known to be 0 or 1 element - it's a C function.
+		err := &ast.Field{Type: ast.NewIdent("error")}
+		l := gtype.Results.List
+		if len(l) == 0 {
+			l = []*ast.Field{err}
+		} else {
+			l = []*ast.Field{l[0], err}
+		}
+		t := new(ast.FuncType)
+		*t = *gtype
+		t.Results = &ast.FieldList{List: l}
+		gtype = t
+	}
+
+	// Go func declaration.
+	d := &ast.FuncDecl{
+		Name: ast.NewIdent(n.Mangle),
+		Type: gtype,
+	}
+
+	// Builtins defined in the C prolog.
+	inProlog := name == "CString" || name == "GoString" || name == "GoStringN" || name == "GoBytes" || name == "_CMalloc"
+
+	if *gccgo {
+		// Gccgo style hooks.
+		fmt.Fprint(fgo2, "\n")
+		cname := fmt.Sprintf("_cgo%s%s", cPrefix, n.Mangle)
+		paramnames := []string(nil)
+		for i, param := range d.Type.Params.List {
+			paramName := fmt.Sprintf("p%d", i)
+			param.Names = []*ast.Ident{ast.NewIdent(paramName)}
+			paramnames = append(paramnames, paramName)
+		}
+
+		conf.Fprint(fgo2, fset, d)
+		fmt.Fprint(fgo2, " {\n")
+		if !inProlog {
+			fmt.Fprint(fgo2, "\tdefer syscall.CgocallDone()\n")
+			fmt.Fprint(fgo2, "\tsyscall.Cgocall()\n")
+		}
+		if n.AddError {
+			fmt.Fprint(fgo2, "\tsyscall.SetErrno(0)\n")
+		}
+		fmt.Fprint(fgo2, "\t")
+		if !void {
+			fmt.Fprint(fgo2, "r := ")
+		}
+		fmt.Fprintf(fgo2, "%s(%s)\n", cname, strings.Join(paramnames, ", "))
+
+		if n.AddError {
+			fmt.Fprint(fgo2, "\te := syscall.GetErrno()\n")
+			fmt.Fprint(fgo2, "\tif e != 0 {\n")
+			fmt.Fprint(fgo2, "\t\treturn ")
+			if !void {
+				fmt.Fprint(fgo2, "r, ")
+			}
+			fmt.Fprint(fgo2, "e\n")
+			fmt.Fprint(fgo2, "\t}\n")
+			fmt.Fprint(fgo2, "\treturn ")
+			if !void {
+				fmt.Fprint(fgo2, "r, ")
+			}
+			fmt.Fprint(fgo2, "nil\n")
+		} else if !void {
+			fmt.Fprint(fgo2, "\treturn r\n")
+		}
+
+		fmt.Fprint(fgo2, "}\n")
+
+		// declare the C function.
+		fmt.Fprintf(fgo2, "//extern _cgo%s%s\n", cPrefix, n.Mangle)
+		d.Name = ast.NewIdent(cname)
+		if n.AddError {
+			l := d.Type.Results.List
+			d.Type.Results.List = l[:len(l)-1]
+		}
+		conf.Fprint(fgo2, fset, d)
+		fmt.Fprint(fgo2, "\n")
+
+		return
+	}
+	conf.Fprint(fgo2, fset, d)
+	fmt.Fprint(fgo2, "\n")
+
+	if inProlog {
+		return
+	}
+
+	var argSize int64
+	_, argSize = p.structType(n)
+
+	// C wrapper calls into gcc, passing a pointer to the argument frame.
+	fmt.Fprintf(fc, "#pragma cgo_import_static _cgo%s%s\n", cPrefix, n.Mangle)
+	fmt.Fprintf(fc, "void _cgo%s%s(void*);\n", cPrefix, n.Mangle)
+	fmt.Fprintf(fc, "\n")
+	fmt.Fprintf(fc, "void\n")
+	if argSize == 0 {
+		argSize++
+	}
+	// TODO(rsc): The struct here should declare pointers only where
+	// there are pointers in the actual argument frame.
+	// This is a workaround for golang.org/issue/6397.
+	fmt.Fprintf(fc, "·%s(struct{", n.Mangle)
+	if n := argSize / p.PtrSize; n > 0 {
+		fmt.Fprintf(fc, "void *y[%d];", n)
+	}
+	if n := argSize % p.PtrSize; n > 0 {
+		fmt.Fprintf(fc, "uint8 x[%d];", n)
+	}
+	fmt.Fprintf(fc, "}p)\n")
+	fmt.Fprintf(fc, "{\n")
+	fmt.Fprintf(fc, "\truntime·cgocall(_cgo%s%s, &p);\n", cPrefix, n.Mangle)
+	if n.AddError {
+		// gcc leaves errno in first word of interface at end of p.
+		// check whether it is zero; if so, turn interface into nil.
+		// if not, turn interface into errno.
+		// Go init function initializes ·_Cerrno with an os.Errno
+		// for us to copy.
+		fmt.Fprintln(fc, `	{
+			int32 e;
+			void **v;
+			v = (void**)(&p+1) - 2;	/* v = final two void* of p */
+			e = *(int32*)v;
+			v[0] = (void*)0xdeadbeef;
+			v[1] = (void*)0xdeadbeef;
+			if(e == 0) {
+				/* nil interface */
+				v[0] = 0;
+				v[1] = 0;
+			} else {
+				·_Cerrno(v, e);	/* fill in v as error for errno e */
+			}
+		}`)
+	}
+	fmt.Fprintf(fc, "}\n")
+	fmt.Fprintf(fc, "\n")
+}
+
+// writeOutput creates stubs for a specific source file to be compiled by 6g
+// (The comments here say 6g and 6c but the code applies to the 8 and 5 tools too.)
+func (p *Package) writeOutput(f *File, srcfile string) {
+	base := srcfile
+	if strings.HasSuffix(base, ".go") {
+		base = base[0 : len(base)-3]
+	}
+	base = strings.Map(slashToUnderscore, base)
+	fgo1 := creat(*objDir + base + ".cgo1.go")
+	fgcc := creat(*objDir + base + ".cgo2.c")
+
+	p.GoFiles = append(p.GoFiles, base+".cgo1.go")
+	p.GccFiles = append(p.GccFiles, base+".cgo2.c")
+
+	// Write Go output: Go input with rewrites of C.xxx to _C_xxx.
+	fmt.Fprintf(fgo1, "// Created by cgo - DO NOT EDIT\n\n")
+	conf.Fprint(fgo1, fset, f.AST)
+
+	// While we process the vars and funcs, also write 6c and gcc output.
+	// Gcc output starts with the preamble.
+	fmt.Fprintf(fgcc, "%s\n", f.Preamble)
+	fmt.Fprintf(fgcc, "%s\n", gccProlog)
+
+	for _, key := range nameKeys(f.Name) {
+		n := f.Name[key]
+		if n.FuncType != nil {
+			p.writeOutputFunc(fgcc, n)
+		}
+	}
+
+	fgo1.Close()
+	fgcc.Close()
+}
+
+// fixGo converts the internal Name.Go field into the name we should show
+// to users in error messages. There's only one for now: on input we rewrite
+// C.malloc into C._CMalloc, so change it back here.
+func fixGo(name string) string {
+	if name == "_CMalloc" {
+		return "malloc"
+	}
+	return name
+}
+
+var isBuiltin = map[string]bool{
+	"_Cfunc_CString":   true,
+	"_Cfunc_GoString":  true,
+	"_Cfunc_GoStringN": true,
+	"_Cfunc_GoBytes":   true,
+	"_Cfunc__CMalloc":  true,
+}
+
+func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
+	name := n.Mangle
+	if isBuiltin[name] || p.Written[name] {
+		// The builtins are already defined in the C prolog, and we don't
+		// want to duplicate function definitions we've already done.
+		return
+	}
+	p.Written[name] = true
+
+	if *gccgo {
+		p.writeGccgoOutputFunc(fgcc, n)
+		return
+	}
+
+	ctype, _ := p.structType(n)
+
+	// Gcc wrapper unpacks the C argument struct
+	// and calls the actual C function.
+	fmt.Fprintf(fgcc, "void\n")
+	fmt.Fprintf(fgcc, "_cgo%s%s(void *v)\n", cPrefix, n.Mangle)
+	fmt.Fprintf(fgcc, "{\n")
+	if n.AddError {
+		fmt.Fprintf(fgcc, "\terrno = 0;\n")
+	}
+	// We're trying to write a gcc struct that matches 6c/8c/5c's layout.
+	// Use packed attribute to force no padding in this struct in case
+	// gcc has different packing requirements.
+	fmt.Fprintf(fgcc, "\t%s %v *a = v;\n", ctype, p.packedAttribute())
+	fmt.Fprintf(fgcc, "\t")
+	if t := n.FuncType.Result; t != nil {
+		fmt.Fprintf(fgcc, "a->r = ")
+		if c := t.C.String(); c[len(c)-1] == '*' {
+			fmt.Fprint(fgcc, "(__typeof__(a->r)) ")
+		}
+	}
+	fmt.Fprintf(fgcc, "%s(", n.C)
+	for i, t := range n.FuncType.Params {
+		if i > 0 {
+			fmt.Fprintf(fgcc, ", ")
+		}
+		// We know the type params are correct, because
+		// the Go equivalents had good type params.
+		// However, our version of the type omits the magic
+		// words const and volatile, which can provoke
+		// C compiler warnings.  Silence them by casting
+		// all pointers to void*.  (Eventually that will produce
+		// other warnings.)
+		if c := t.C.String(); c[len(c)-1] == '*' {
+			fmt.Fprintf(fgcc, "(void*)")
+		}
+		fmt.Fprintf(fgcc, "a->p%d", i)
+	}
+	fmt.Fprintf(fgcc, ");\n")
+	if n.AddError {
+		fmt.Fprintf(fgcc, "\t*(int*)(a->e) = errno;\n")
+	}
+	fmt.Fprintf(fgcc, "}\n")
+	fmt.Fprintf(fgcc, "\n")
+}
+
+// Write out a wrapper for a function when using gccgo.  This is a
+// simple wrapper that just calls the real function.  We only need a
+// wrapper to support static functions in the prologue--without a
+// wrapper, we can't refer to the function, since the reference is in
+// a different file.
+func (p *Package) writeGccgoOutputFunc(fgcc *os.File, n *Name) {
+	if t := n.FuncType.Result; t != nil {
+		fmt.Fprintf(fgcc, "%s\n", t.C.String())
+	} else {
+		fmt.Fprintf(fgcc, "void\n")
+	}
+	fmt.Fprintf(fgcc, "_cgo%s%s(", cPrefix, n.Mangle)
+	for i, t := range n.FuncType.Params {
+		if i > 0 {
+			fmt.Fprintf(fgcc, ", ")
+		}
+		c := t.Typedef
+		if c == "" {
+			c = t.C.String()
+		}
+		fmt.Fprintf(fgcc, "%s p%d", c, i)
+	}
+	fmt.Fprintf(fgcc, ")\n")
+	fmt.Fprintf(fgcc, "{\n")
+	fmt.Fprintf(fgcc, "\t")
+	if t := n.FuncType.Result; t != nil {
+		fmt.Fprintf(fgcc, "return ")
+		// Cast to void* to avoid warnings due to omitted qualifiers.
+		if c := t.C.String(); c[len(c)-1] == '*' {
+			fmt.Fprintf(fgcc, "(void*)")
+		}
+	}
+	fmt.Fprintf(fgcc, "%s(", n.C)
+	for i, t := range n.FuncType.Params {
+		if i > 0 {
+			fmt.Fprintf(fgcc, ", ")
+		}
+		// Cast to void* to avoid warnings due to omitted qualifiers.
+		if c := t.C.String(); c[len(c)-1] == '*' {
+			fmt.Fprintf(fgcc, "(void*)")
+		}
+		fmt.Fprintf(fgcc, "p%d", i)
+	}
+	fmt.Fprintf(fgcc, ");\n")
+	fmt.Fprintf(fgcc, "}\n")
+	fmt.Fprintf(fgcc, "\n")
+}
+
+// packedAttribute returns host compiler struct attribute that will be
+// used to match 6c/8c/5c's struct layout. For example, on 386 Windows,
+// gcc wants to 8-align int64s, but 8c does not.
+// Use __gcc_struct__ to work around http://gcc.gnu.org/PR52991 on x86,
+// and http://golang.org/issue/5603.
+func (p *Package) packedAttribute() string {
+	s := "__attribute__((__packed__"
+	if !strings.Contains(p.gccBaseCmd()[0], "clang") && (goarch == "amd64" || goarch == "386") {
+		s += ", __gcc_struct__"
+	}
+	return s + "))"
+}
+
+// Write out the various stubs we need to support functions exported
+// from Go so that they are callable from C.
+func (p *Package) writeExports(fgo2, fc, fm *os.File) {
+	fgcc := creat(*objDir + "_cgo_export.c")
+	fgcch := creat(*objDir + "_cgo_export.h")
+
+	fmt.Fprintf(fgcch, "/* Created by cgo - DO NOT EDIT. */\n")
+	fmt.Fprintf(fgcch, "%s\n", p.Preamble)
+	fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog())
+
+	fmt.Fprintf(fgcc, "/* Created by cgo - DO NOT EDIT. */\n")
+	fmt.Fprintf(fgcc, "#include \"_cgo_export.h\"\n")
+
+	fmt.Fprintf(fgcc, "\nextern void crosscall2(void (*fn)(void *, int), void *, int);\n\n")
+
+	for _, exp := range p.ExpFunc {
+		fn := exp.Func
+
+		// Construct a gcc struct matching the 6c argument and
+		// result frame.  The gcc struct will be compiled with
+		// __attribute__((packed)) so all padding must be accounted
+		// for explicitly.
+		ctype := "struct {\n"
+		off := int64(0)
+		npad := 0
+		if fn.Recv != nil {
+			t := p.cgoType(fn.Recv.List[0].Type)
+			ctype += fmt.Sprintf("\t\t%s recv;\n", t.C)
+			off += t.Size
+		}
+		fntype := fn.Type
+		forFieldList(fntype.Params,
+			func(i int, atype ast.Expr) {
+				t := p.cgoType(atype)
+				if off%t.Align != 0 {
+					pad := t.Align - off%t.Align
+					ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad)
+					off += pad
+					npad++
+				}
+				ctype += fmt.Sprintf("\t\t%s p%d;\n", t.C, i)
+				off += t.Size
+			})
+		if off%p.PtrSize != 0 {
+			pad := p.PtrSize - off%p.PtrSize
+			ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad)
+			off += pad
+			npad++
+		}
+		forFieldList(fntype.Results,
+			func(i int, atype ast.Expr) {
+				t := p.cgoType(atype)
+				if off%t.Align != 0 {
+					pad := t.Align - off%t.Align
+					ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad)
+					off += pad
+					npad++
+				}
+				ctype += fmt.Sprintf("\t\t%s r%d;\n", t.C, i)
+				off += t.Size
+			})
+		if off%p.PtrSize != 0 {
+			pad := p.PtrSize - off%p.PtrSize
+			ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad)
+			off += pad
+			npad++
+		}
+		if ctype == "struct {\n" {
+			ctype += "\t\tchar unused;\n" // avoid empty struct
+		}
+		ctype += "\t}"
+
+		// Get the return type of the wrapper function
+		// compiled by gcc.
+		gccResult := ""
+		if fntype.Results == nil || len(fntype.Results.List) == 0 {
+			gccResult = "void"
+		} else if len(fntype.Results.List) == 1 && len(fntype.Results.List[0].Names) <= 1 {
+			gccResult = p.cgoType(fntype.Results.List[0].Type).C.String()
+		} else {
+			fmt.Fprintf(fgcch, "\n/* Return type for %s */\n", exp.ExpName)
+			fmt.Fprintf(fgcch, "struct %s_return {\n", exp.ExpName)
+			forFieldList(fntype.Results,
+				func(i int, atype ast.Expr) {
+					fmt.Fprintf(fgcch, "\t%s r%d;\n", p.cgoType(atype).C, i)
+				})
+			fmt.Fprintf(fgcch, "};\n")
+			gccResult = "struct " + exp.ExpName + "_return"
+		}
+
+		// Build the wrapper function compiled by gcc.
+		s := fmt.Sprintf("%s %s(", gccResult, exp.ExpName)
+		if fn.Recv != nil {
+			s += p.cgoType(fn.Recv.List[0].Type).C.String()
+			s += " recv"
+		}
+		forFieldList(fntype.Params,
+			func(i int, atype ast.Expr) {
+				if i > 0 || fn.Recv != nil {
+					s += ", "
+				}
+				s += fmt.Sprintf("%s p%d", p.cgoType(atype).C, i)
+			})
+		s += ")"
+		fmt.Fprintf(fgcch, "\nextern %s;\n", s)
+
+		fmt.Fprintf(fgcc, "extern void _cgoexp%s_%s(void *, int);\n", cPrefix, exp.ExpName)
+		fmt.Fprintf(fgcc, "\n%s\n", s)
+		fmt.Fprintf(fgcc, "{\n")
+		fmt.Fprintf(fgcc, "\t%s %v a;\n", ctype, p.packedAttribute())
+		if gccResult != "void" && (len(fntype.Results.List) > 1 || len(fntype.Results.List[0].Names) > 1) {
+			fmt.Fprintf(fgcc, "\t%s r;\n", gccResult)
+		}
+		if fn.Recv != nil {
+			fmt.Fprintf(fgcc, "\ta.recv = recv;\n")
+		}
+		forFieldList(fntype.Params,
+			func(i int, atype ast.Expr) {
+				fmt.Fprintf(fgcc, "\ta.p%d = p%d;\n", i, i)
+			})
+		fmt.Fprintf(fgcc, "\tcrosscall2(_cgoexp%s_%s, &a, %d);\n", cPrefix, exp.ExpName, off)
+		if gccResult != "void" {
+			if len(fntype.Results.List) == 1 && len(fntype.Results.List[0].Names) <= 1 {
+				fmt.Fprintf(fgcc, "\treturn a.r0;\n")
+			} else {
+				forFieldList(fntype.Results,
+					func(i int, atype ast.Expr) {
+						fmt.Fprintf(fgcc, "\tr.r%d = a.r%d;\n", i, i)
+					})
+				fmt.Fprintf(fgcc, "\treturn r;\n")
+			}
+		}
+		fmt.Fprintf(fgcc, "}\n")
+
+		// Build the wrapper function compiled by 6c/8c
+		goname := exp.Func.Name.Name
+		if fn.Recv != nil {
+			goname = "_cgoexpwrap" + cPrefix + "_" + fn.Recv.List[0].Names[0].Name + "_" + goname
+		}
+		fmt.Fprintf(fc, "#pragma cgo_export_dynamic %s\n", goname)
+		fmt.Fprintf(fc, "extern void ·%s();\n\n", goname)
+		fmt.Fprintf(fc, "#pragma cgo_export_static _cgoexp%s_%s\n", cPrefix, exp.ExpName)
+		fmt.Fprintf(fc, "#pragma textflag 7\n") // no split stack, so no use of m or g
+		fmt.Fprintf(fc, "void\n")
+		fmt.Fprintf(fc, "_cgoexp%s_%s(void *a, int32 n)\n", cPrefix, exp.ExpName)
+		fmt.Fprintf(fc, "{\n")
+		fmt.Fprintf(fc, "\truntime·cgocallback(·%s, a, n);\n", goname)
+		fmt.Fprintf(fc, "}\n")
+
+		fmt.Fprintf(fm, "int _cgoexp%s_%s;\n", cPrefix, exp.ExpName)
+
+		// Calling a function with a receiver from C requires
+		// a Go wrapper function.
+		if fn.Recv != nil {
+			fmt.Fprintf(fgo2, "func %s(recv ", goname)
+			conf.Fprint(fgo2, fset, fn.Recv.List[0].Type)
+			forFieldList(fntype.Params,
+				func(i int, atype ast.Expr) {
+					fmt.Fprintf(fgo2, ", p%d ", i)
+					conf.Fprint(fgo2, fset, atype)
+				})
+			fmt.Fprintf(fgo2, ")")
+			if gccResult != "void" {
+				fmt.Fprint(fgo2, " (")
+				forFieldList(fntype.Results,
+					func(i int, atype ast.Expr) {
+						if i > 0 {
+							fmt.Fprint(fgo2, ", ")
+						}
+						conf.Fprint(fgo2, fset, atype)
+					})
+				fmt.Fprint(fgo2, ")")
+			}
+			fmt.Fprint(fgo2, " {\n")
+			fmt.Fprint(fgo2, "\t")
+			if gccResult != "void" {
+				fmt.Fprint(fgo2, "return ")
+			}
+			fmt.Fprintf(fgo2, "recv.%s(", exp.Func.Name)
+			forFieldList(fntype.Params,
+				func(i int, atype ast.Expr) {
+					if i > 0 {
+						fmt.Fprint(fgo2, ", ")
+					}
+					fmt.Fprintf(fgo2, "p%d", i)
+				})
+			fmt.Fprint(fgo2, ")\n")
+			fmt.Fprint(fgo2, "}\n")
+		}
+	}
+}
+
+// Write out the C header allowing C code to call exported gccgo functions.
+func (p *Package) writeGccgoExports(fgo2, fc, fm *os.File) {
+	fgcc := creat(*objDir + "_cgo_export.c")
+	fgcch := creat(*objDir + "_cgo_export.h")
+
+	gccgoSymbolPrefix := p.gccgoSymbolPrefix()
+
+	fmt.Fprintf(fgcch, "/* Created by cgo - DO NOT EDIT. */\n")
+	fmt.Fprintf(fgcch, "%s\n", p.Preamble)
+	fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog())
+
+	fmt.Fprintf(fgcc, "/* Created by cgo - DO NOT EDIT. */\n")
+	fmt.Fprintf(fgcc, "#include \"_cgo_export.h\"\n")
+
+	fmt.Fprintf(fm, "#include \"_cgo_export.h\"\n")
+
+	for _, exp := range p.ExpFunc {
+		fn := exp.Func
+		fntype := fn.Type
+
+		cdeclBuf := new(bytes.Buffer)
+		resultCount := 0
+		forFieldList(fntype.Results,
+			func(i int, atype ast.Expr) { resultCount++ })
+		switch resultCount {
+		case 0:
+			fmt.Fprintf(cdeclBuf, "void")
+		case 1:
+			forFieldList(fntype.Results,
+				func(i int, atype ast.Expr) {
+					t := p.cgoType(atype)
+					fmt.Fprintf(cdeclBuf, "%s", t.C)
+				})
+		default:
+			// Declare a result struct.
+			fmt.Fprintf(fgcch, "struct %s_result {\n", exp.ExpName)
+			forFieldList(fntype.Results,
+				func(i int, atype ast.Expr) {
+					t := p.cgoType(atype)
+					fmt.Fprintf(fgcch, "\t%s r%d;\n", t.C, i)
+				})
+			fmt.Fprintf(fgcch, "};\n")
+			fmt.Fprintf(cdeclBuf, "struct %s_result", exp.ExpName)
+		}
+
+		cRet := cdeclBuf.String()
+
+		cdeclBuf = new(bytes.Buffer)
+		fmt.Fprintf(cdeclBuf, "(")
+		if fn.Recv != nil {
+			fmt.Fprintf(cdeclBuf, "%s recv", p.cgoType(fn.Recv.List[0].Type).C.String())
+		}
+		// Function parameters.
+		forFieldList(fntype.Params,
+			func(i int, atype ast.Expr) {
+				if i > 0 || fn.Recv != nil {
+					fmt.Fprintf(cdeclBuf, ", ")
+				}
+				t := p.cgoType(atype)
+				fmt.Fprintf(cdeclBuf, "%s p%d", t.C, i)
+			})
+		fmt.Fprintf(cdeclBuf, ")")
+		cParams := cdeclBuf.String()
+
+		// We need to use a name that will be exported by the
+		// Go code; otherwise gccgo will make it static and we
+		// will not be able to link against it from the C
+		// code.
+		goName := "Cgoexp_" + exp.ExpName
+		fmt.Fprintf(fgcch, `extern %s %s %s __asm__("%s.%s");`, cRet, goName, cParams, gccgoSymbolPrefix, goName)
+		fmt.Fprint(fgcch, "\n")
+
+		// Use a #define so that the C code that includes
+		// cgo_export.h will be able to refer to the Go
+		// function using the expected name.
+		fmt.Fprintf(fgcch, "#define %s %s\n", exp.ExpName, goName)
+
+		// Use a #undef in _cgo_export.c so that we ignore the
+		// #define from cgo_export.h, since here we are
+		// defining the real function.
+		fmt.Fprintf(fgcc, "#undef %s\n", exp.ExpName)
+
+		fmt.Fprint(fgcc, "\n")
+		fmt.Fprintf(fgcc, "%s %s %s {\n", cRet, exp.ExpName, cParams)
+		fmt.Fprint(fgcc, "\t")
+		if resultCount > 0 {
+			fmt.Fprint(fgcc, "return ")
+		}
+		fmt.Fprintf(fgcc, "%s(", goName)
+		if fn.Recv != nil {
+			fmt.Fprint(fgcc, "recv")
+		}
+		forFieldList(fntype.Params,
+			func(i int, atype ast.Expr) {
+				if i > 0 || fn.Recv != nil {
+					fmt.Fprintf(fgcc, ", ")
+				}
+				fmt.Fprintf(fgcc, "p%d", i)
+			})
+		fmt.Fprint(fgcc, ");\n")
+		fmt.Fprint(fgcc, "}\n")
+
+		// Dummy declaration for _cgo_main.c
+		fmt.Fprintf(fm, "%s %s %s {}\n", cRet, goName, cParams)
+
+		// For gccgo we use a wrapper function in Go, in order
+		// to call CgocallBack and CgocallBackDone.
+
+		// This code uses printer.Fprint, not conf.Fprint,
+		// because we don't want //line comments in the middle
+		// of the function types.
+		fmt.Fprint(fgo2, "\n")
+		fmt.Fprintf(fgo2, "func %s(", goName)
+		if fn.Recv != nil {
+			fmt.Fprint(fgo2, "recv ")
+			printer.Fprint(fgo2, fset, fn.Recv.List[0].Type)
+		}
+		forFieldList(fntype.Params,
+			func(i int, atype ast.Expr) {
+				if i > 0 || fn.Recv != nil {
+					fmt.Fprintf(fgo2, ", ")
+				}
+				fmt.Fprintf(fgo2, "p%d ", i)
+				printer.Fprint(fgo2, fset, atype)
+			})
+		fmt.Fprintf(fgo2, ")")
+		if resultCount > 0 {
+			fmt.Fprintf(fgo2, " (")
+			forFieldList(fntype.Results,
+				func(i int, atype ast.Expr) {
+					if i > 0 {
+						fmt.Fprint(fgo2, ", ")
+					}
+					printer.Fprint(fgo2, fset, atype)
+				})
+			fmt.Fprint(fgo2, ")")
+		}
+		fmt.Fprint(fgo2, " {\n")
+		fmt.Fprint(fgo2, "\tsyscall.CgocallBack()\n")
+		fmt.Fprint(fgo2, "\tdefer syscall.CgocallBackDone()\n")
+		fmt.Fprint(fgo2, "\t")
+		if resultCount > 0 {
+			fmt.Fprint(fgo2, "return ")
+		}
+		if fn.Recv != nil {
+			fmt.Fprint(fgo2, "recv.")
+		}
+		fmt.Fprintf(fgo2, "%s(", exp.Func.Name)
+		forFieldList(fntype.Params,
+			func(i int, atype ast.Expr) {
+				if i > 0 {
+					fmt.Fprint(fgo2, ", ")
+				}
+				fmt.Fprintf(fgo2, "p%d", i)
+			})
+		fmt.Fprint(fgo2, ")\n")
+		fmt.Fprint(fgo2, "}\n")
+	}
+}
+
+// Return the package prefix when using gccgo.
+func (p *Package) gccgoSymbolPrefix() string {
+	if !*gccgo {
+		return ""
+	}
+
+	clean := func(r rune) rune {
+		switch {
+		case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
+			'0' <= r && r <= '9':
+			return r
+		}
+		return '_'
+	}
+
+	if *gccgopkgpath != "" {
+		return strings.Map(clean, *gccgopkgpath)
+	}
+	if *gccgoprefix == "" && p.PackageName == "main" {
+		return "main"
+	}
+	prefix := strings.Map(clean, *gccgoprefix)
+	if prefix == "" {
+		prefix = "go"
+	}
+	return prefix + "." + p.PackageName
+}
+
+// Call a function for each entry in an ast.FieldList, passing the
+// index into the list and the type.
+func forFieldList(fl *ast.FieldList, fn func(int, ast.Expr)) {
+	if fl == nil {
+		return
+	}
+	i := 0
+	for _, r := range fl.List {
+		if r.Names == nil {
+			fn(i, r.Type)
+			i++
+		} else {
+			for _ = range r.Names {
+				fn(i, r.Type)
+				i++
+			}
+		}
+	}
+}
+
+func c(repr string, args ...interface{}) *TypeRepr {
+	return &TypeRepr{repr, args}
+}
+
+// Map predeclared Go types to Type.
+var goTypes = map[string]*Type{
+	"bool":       {Size: 1, Align: 1, C: c("GoUint8")},
+	"byte":       {Size: 1, Align: 1, C: c("GoUint8")},
+	"int":        {Size: 0, Align: 0, C: c("GoInt")},
+	"uint":       {Size: 0, Align: 0, C: c("GoUint")},
+	"rune":       {Size: 4, Align: 4, C: c("GoInt32")},
+	"int8":       {Size: 1, Align: 1, C: c("GoInt8")},
+	"uint8":      {Size: 1, Align: 1, C: c("GoUint8")},
+	"int16":      {Size: 2, Align: 2, C: c("GoInt16")},
+	"uint16":     {Size: 2, Align: 2, C: c("GoUint16")},
+	"int32":      {Size: 4, Align: 4, C: c("GoInt32")},
+	"uint32":     {Size: 4, Align: 4, C: c("GoUint32")},
+	"int64":      {Size: 8, Align: 8, C: c("GoInt64")},
+	"uint64":     {Size: 8, Align: 8, C: c("GoUint64")},
+	"float32":    {Size: 4, Align: 4, C: c("GoFloat32")},
+	"float64":    {Size: 8, Align: 8, C: c("GoFloat64")},
+	"complex64":  {Size: 8, Align: 8, C: c("GoComplex64")},
+	"complex128": {Size: 16, Align: 16, C: c("GoComplex128")},
+}
+
+// Map an ast type to a Type.
+func (p *Package) cgoType(e ast.Expr) *Type {
+	switch t := e.(type) {
+	case *ast.StarExpr:
+		x := p.cgoType(t.X)
+		return &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("%s*", x.C)}
+	case *ast.ArrayType:
+		if t.Len == nil {
+			// Slice: pointer, len, cap.
+			return &Type{Size: p.PtrSize * 3, Align: p.PtrSize, C: c("GoSlice")}
+		}
+	case *ast.StructType:
+		// TODO
+	case *ast.FuncType:
+		return &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*")}
+	case *ast.InterfaceType:
+		return &Type{Size: 2 * p.PtrSize, Align: p.PtrSize, C: c("GoInterface")}
+	case *ast.MapType:
+		return &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("GoMap")}
+	case *ast.ChanType:
+		return &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("GoChan")}
+	case *ast.Ident:
+		// Look up the type in the top level declarations.
+		// TODO: Handle types defined within a function.
+		for _, d := range p.Decl {
+			gd, ok := d.(*ast.GenDecl)
+			if !ok || gd.Tok != token.TYPE {
+				continue
+			}
+			for _, spec := range gd.Specs {
+				ts, ok := spec.(*ast.TypeSpec)
+				if !ok {
+					continue
+				}
+				if ts.Name.Name == t.Name {
+					return p.cgoType(ts.Type)
+				}
+			}
+		}
+		if def := typedef[t.Name]; def != nil {
+			return def
+		}
+		if t.Name == "uintptr" {
+			return &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("GoUintptr")}
+		}
+		if t.Name == "string" {
+			// The string data is 1 pointer + 1 (pointer-sized) int.
+			return &Type{Size: 2 * p.PtrSize, Align: p.PtrSize, C: c("GoString")}
+		}
+		if t.Name == "error" {
+			return &Type{Size: 2 * p.PtrSize, Align: p.PtrSize, C: c("GoInterface")}
+		}
+		if r, ok := goTypes[t.Name]; ok {
+			if r.Size == 0 { // int or uint
+				rr := new(Type)
+				*rr = *r
+				rr.Size = p.IntSize
+				rr.Align = p.IntSize
+				r = rr
+			}
+			if r.Align > p.PtrSize {
+				r.Align = p.PtrSize
+			}
+			return r
+		}
+		error_(e.Pos(), "unrecognized Go type %s", t.Name)
+		return &Type{Size: 4, Align: 4, C: c("int")}
+	case *ast.SelectorExpr:
+		id, ok := t.X.(*ast.Ident)
+		if ok && id.Name == "unsafe" && t.Sel.Name == "Pointer" {
+			return &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*")}
+		}
+	}
+	error_(e.Pos(), "Go type not supported in export: %s", gofmt(e))
+	return &Type{Size: 4, Align: 4, C: c("int")}
+}
+
+const gccProlog = `
+// Usual nonsense: if x and y are not equal, the type will be invalid
+// (have a negative array count) and an inscrutable error will come
+// out of the compiler and hopefully mention "name".
+#define __cgo_compile_assert_eq(x, y, name) typedef char name[(x-y)*(x-y)*-2+1];
+
+// Check at compile time that the sizes we use match our expectations.
+#define __cgo_size_assert(t, n) __cgo_compile_assert_eq(sizeof(t), n, _cgo_sizeof_##t##_is_not_##n)
+
+__cgo_size_assert(char, 1)
+__cgo_size_assert(short, 2)
+__cgo_size_assert(int, 4)
+typedef long long __cgo_long_long;
+__cgo_size_assert(__cgo_long_long, 8)
+__cgo_size_assert(float, 4)
+__cgo_size_assert(double, 8)
+
+#include <errno.h>
+#include <string.h>
+`
+
+const builtinProlog = `
+#include <sys/types.h> /* for size_t below */
+
+/* Define intgo when compiling with GCC.  */
+#ifdef __PTRDIFF_TYPE__
+typedef __PTRDIFF_TYPE__ intgo;
+#elif defined(_LP64)
+typedef long long intgo;
+#else
+typedef int intgo;
+#endif
+
+typedef struct { char *p; intgo n; } _GoString_;
+typedef struct { char *p; intgo n; intgo c; } _GoBytes_;
+_GoString_ GoString(char *p);
+_GoString_ GoStringN(char *p, int l);
+_GoBytes_ GoBytes(void *p, int n);
+char *CString(_GoString_);
+void *_CMalloc(size_t);
+`
+
+const cProlog = `
+#include "runtime.h"
+#include "cgocall.h"
+
+void ·_Cerrno(void*, int32);
+
+void
+·_Cfunc_GoString(int8 *p, String s)
+{
+	s = runtime·gostring((byte*)p);
+	FLUSH(&s);
+}
+
+void
+·_Cfunc_GoStringN(int8 *p, int32 l, String s)
+{
+	s = runtime·gostringn((byte*)p, l);
+	FLUSH(&s);
+}
+
+void
+·_Cfunc_GoBytes(int8 *p, int32 l, Slice s)
+{
+	s = runtime·gobytes((byte*)p, l);
+	FLUSH(&s);
+}
+
+void
+·_Cfunc_CString(String s, int8 *p)
+{
+	p = runtime·cmalloc(s.len+1);
+	runtime·memmove((byte*)p, s.str, s.len);
+	p[s.len] = 0;
+	FLUSH(&p);
+}
+
+void
+·_Cfunc__CMalloc(uintptr n, int8 *p)
+{
+	p = runtime·cmalloc(n);
+	FLUSH(&p);
+}
+`
+
+func (p *Package) cPrologGccgo() string {
+	return strings.Replace(cPrologGccgo, "PREFIX", cPrefix, -1)
+}
+
+const cPrologGccgo = `
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef unsigned char byte;
+typedef intptr_t intgo;
+
+struct __go_string {
+	const unsigned char *__data;
+	intgo __length;
+};
+
+typedef struct __go_open_array {
+	void* __values;
+	intgo __count;
+	intgo __capacity;
+} Slice;
+
+struct __go_string __go_byte_array_to_string(const void* p, intgo len);
+struct __go_open_array __go_string_to_byte_array (struct __go_string str);
+
+const char *_cgoPREFIX_Cfunc_CString(struct __go_string s) {
+	char *p = malloc(s.__length+1);
+	memmove(p, s.__data, s.__length);
+	p[s.__length] = 0;
+	return p;
+}
+
+struct __go_string _cgoPREFIX_Cfunc_GoString(char *p) {
+	intgo len = (p != NULL) ? strlen(p) : 0;
+	return __go_byte_array_to_string(p, len);
+}
+
+struct __go_string _cgoPREFIX_Cfunc_GoStringN(char *p, int32_t n) {
+	return __go_byte_array_to_string(p, n);
+}
+
+Slice _cgoPREFIX_Cfunc_GoBytes(char *p, int32_t n) {
+	struct __go_string s = { (const unsigned char *)p, n };
+	return __go_string_to_byte_array(s);
+}
+
+extern void runtime_throw(const char *);
+void *_cgoPREFIX_Cfunc__CMalloc(size_t n) {
+        void *p = malloc(n);
+        if(p == NULL && n == 0)
+                p = malloc(1);
+        if(p == NULL)
+                runtime_throw("runtime: C malloc failed");
+        return p;
+}
+`
+
+func (p *Package) gccExportHeaderProlog() string {
+	return strings.Replace(gccExportHeaderProlog, "GOINTBITS", fmt.Sprint(8*p.IntSize), -1)
+}
+
+const gccExportHeaderProlog = `
+typedef signed char GoInt8;
+typedef unsigned char GoUint8;
+typedef short GoInt16;
+typedef unsigned short GoUint16;
+typedef int GoInt32;
+typedef unsigned int GoUint32;
+typedef long long GoInt64;
+typedef unsigned long long GoUint64;
+typedef GoIntGOINTBITS GoInt;
+typedef GoUintGOINTBITS GoUint;
+typedef __SIZE_TYPE__ GoUintptr;
+typedef float GoFloat32;
+typedef double GoFloat64;
+typedef __complex float GoComplex64;
+typedef __complex double GoComplex128;
+
+typedef struct { char *p; GoInt n; } GoString;
+typedef void *GoMap;
+typedef void *GoChan;
+typedef struct { void *t; void *v; } GoInterface;
+typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
+`
diff --git a/third_party/gofrontend/libgo/go/cmd/cgo/util.go b/third_party/gofrontend/libgo/go/cmd/cgo/util.go
new file mode 100644
index 0000000..4e7800d
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/cgo/util.go
@@ -0,0 +1,84 @@
+// 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 main
+
+import (
+	"bytes"
+	"fmt"
+	"go/token"
+	"os"
+	"os/exec"
+)
+
+// run runs the command argv, feeding in stdin on standard input.
+// It returns the output to standard output and standard error.
+// ok indicates whether the command exited successfully.
+func run(stdin []byte, argv []string) (stdout, stderr []byte, ok bool) {
+	p := exec.Command(argv[0], argv[1:]...)
+	p.Stdin = bytes.NewReader(stdin)
+	var bout, berr bytes.Buffer
+	p.Stdout = &bout
+	p.Stderr = &berr
+	err := p.Run()
+	if _, ok := err.(*exec.ExitError); err != nil && !ok {
+		fatalf("%s", err)
+	}
+	ok = p.ProcessState.Success()
+	stdout, stderr = bout.Bytes(), berr.Bytes()
+	return
+}
+
+func lineno(pos token.Pos) string {
+	return fset.Position(pos).String()
+}
+
+// Die with an error message.
+func fatalf(msg string, args ...interface{}) {
+	// If we've already printed other errors, they might have
+	// caused the fatal condition.  Assume they're enough.
+	if nerrors == 0 {
+		fmt.Fprintf(os.Stderr, msg+"\n", args...)
+	}
+	os.Exit(2)
+}
+
+var nerrors int
+
+func error_(pos token.Pos, msg string, args ...interface{}) {
+	nerrors++
+	if pos.IsValid() {
+		fmt.Fprintf(os.Stderr, "%s: ", fset.Position(pos).String())
+	}
+	fmt.Fprintf(os.Stderr, msg, args...)
+	fmt.Fprintf(os.Stderr, "\n")
+}
+
+// isName returns true if s is a valid C identifier
+func isName(s string) bool {
+	for i, v := range s {
+		if v != '_' && (v < 'A' || v > 'Z') && (v < 'a' || v > 'z') && (v < '0' || v > '9') {
+			return false
+		}
+		if i == 0 && '0' <= v && v <= '9' {
+			return false
+		}
+	}
+	return s != ""
+}
+
+func creat(name string) *os.File {
+	f, err := os.Create(name)
+	if err != nil {
+		fatalf("%s", err)
+	}
+	return f
+}
+
+func slashToUnderscore(c rune) rune {
+	if c == '/' || c == '\\' || c == ':' {
+		c = '_'
+	}
+	return c
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/bootstrap.go b/third_party/gofrontend/libgo/go/cmd/go/bootstrap.go
new file mode 100644
index 0000000..dc7ed5f
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/bootstrap.go
@@ -0,0 +1,30 @@
+// 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.
+
+// +build cmd_go_bootstrap
+
+// This code is compiled only into the bootstrap 'go' binary.
+// These stubs avoid importing packages with large dependency
+// trees, like the use of "net/http" in vcs.go.
+
+package main
+
+import (
+	"errors"
+	"io"
+)
+
+var errHTTP = errors.New("no http in bootstrap go command")
+
+func httpGET(url string) ([]byte, error) {
+	return nil, errHTTP
+}
+
+func httpsOrHTTP(importPath string) (string, io.ReadCloser, error) {
+	return "", nil, errHTTP
+}
+
+func parseMetaGoImports(r io.Reader) ([]metaImport, error) {
+	panic("unreachable")
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/build.go b/third_party/gofrontend/libgo/go/cmd/go/build.go
new file mode 100644
index 0000000..cead0fa
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/build.go
@@ -0,0 +1,2603 @@
+// Copyright 2011 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 (
+	"bufio"
+	"bytes"
+	"container/heap"
+	"errors"
+	"flag"
+	"fmt"
+	"go/build"
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	"os/exec"
+	"path"
+	"path/filepath"
+	"regexp"
+	"runtime"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+)
+
+var cmdBuild = &Command{
+	UsageLine: "build [-o output] [-i] [build flags] [packages]",
+	Short:     "compile packages and dependencies",
+	Long: `
+Build compiles the packages named by the import paths,
+along with their dependencies, but it does not install the results.
+
+If the arguments are a list of .go files, build treats them as a list
+of source files specifying a single package.
+
+When the command line specifies a single main package,
+build writes the resulting executable to output.
+Otherwise build compiles the packages but discards the results,
+serving only as a check that the packages can be built.
+
+The -o flag specifies the output file name. If not specified, the
+output file name depends on the arguments and derives from the name
+of the package, such as p.a for package p, unless p is 'main'. If
+the package is main and file names are provided, the file name
+derives from the first file name mentioned, such as f1 for 'go build
+f1.go f2.go'; with no files provided ('go build'), the output file
+name is the base name of the containing directory.
+
+The -i flag installs the packages that are dependencies of the target.
+
+The build flags are shared by the build, clean, get, install, list, run,
+and test commands:
+
+	-a
+		force rebuilding of packages that are already up-to-date.
+	-n
+		print the commands but do not run them.
+	-p n
+		the number of builds that can be run in parallel.
+		The default is the number of CPUs available.
+	-race
+		enable data race detection.
+		Supported only on linux/amd64, darwin/amd64 and windows/amd64.
+	-v
+		print the names of packages as they are compiled.
+	-work
+		print the name of the temporary work directory and
+		do not delete it when exiting.
+	-x
+		print the commands.
+
+	-ccflags 'arg list'
+		arguments to pass on each 5c, 6c, or 8c compiler invocation.
+	-compiler name
+		name of compiler to use, as in runtime.Compiler (gccgo or gc).
+	-gccgoflags 'arg list'
+		arguments to pass on each gccgo compiler/linker invocation.
+	-gcflags 'arg list'
+		arguments to pass on each 5g, 6g, or 8g compiler invocation.
+	-installsuffix suffix
+		a suffix to use in the name of the package installation directory,
+		in order to keep output separate from default builds.
+		If using the -race flag, the install suffix is automatically set to race
+		or, if set explicitly, has _race appended to it.
+	-ldflags 'flag list'
+		arguments to pass on each 5l, 6l, or 8l linker invocation.
+	-tags 'tag list'
+		a list of build tags to consider satisfied during the build.
+		For more information about build tags, see the description of
+		build constraints in the documentation for the go/build package.
+
+The list flags accept a space-separated list of strings. To embed spaces
+in an element in the list, surround it with either single or double quotes.
+
+For more about specifying packages, see 'go help packages'.
+For more about where packages and binaries are installed,
+run 'go help gopath'.  For more about calling between Go and C/C++,
+run 'go help c'.
+
+See also: go install, go get, go clean.
+	`,
+}
+
+func init() {
+	// break init cycle
+	cmdBuild.Run = runBuild
+	cmdInstall.Run = runInstall
+
+	cmdBuild.Flag.BoolVar(&buildI, "i", false, "")
+
+	addBuildFlags(cmdBuild)
+	addBuildFlags(cmdInstall)
+}
+
+// Flags set by multiple commands.
+var buildA bool               // -a flag
+var buildN bool               // -n flag
+var buildP = runtime.NumCPU() // -p flag
+var buildV bool               // -v flag
+var buildX bool               // -x flag
+var buildI bool               // -i flag
+var buildO = cmdBuild.Flag.String("o", "", "output file")
+var buildWork bool           // -work flag
+var buildGcflags []string    // -gcflags flag
+var buildCcflags []string    // -ccflags flag
+var buildLdflags []string    // -ldflags flag
+var buildGccgoflags []string // -gccgoflags flag
+var buildRace bool           // -race flag
+
+var reqPkgSrc bool // req src for Imports
+var buildContext = build.Default
+var buildToolchain toolchain = noToolchain{}
+
+// buildCompiler implements flag.Var.
+// It implements Set by updating both
+// buildToolchain and buildContext.Compiler.
+type buildCompiler struct{}
+
+func (c buildCompiler) Set(value string) error {
+	switch value {
+	case "gc":
+		buildToolchain = gcToolchain{}
+	case "gccgo":
+		buildToolchain = gccgoToolchain{}
+	default:
+		return fmt.Errorf("unknown compiler %q", value)
+	}
+	buildContext.Compiler = value
+	return nil
+}
+
+func (c buildCompiler) String() string {
+	return buildContext.Compiler
+}
+
+func init() {
+	switch build.Default.Compiler {
+	case "gc":
+		buildToolchain = gcToolchain{}
+	case "gccgo":
+		buildToolchain = gccgoToolchain{}
+	}
+}
+
+// addBuildFlags adds the flags common to the build, clean, get,
+// install, list, run, and test commands.
+func addBuildFlags(cmd *Command) {
+	// NOTE: If you add flags here, also add them to testflag.go.
+	cmd.Flag.BoolVar(&buildA, "a", false, "")
+	cmd.Flag.BoolVar(&buildN, "n", false, "")
+	cmd.Flag.IntVar(&buildP, "p", buildP, "")
+	cmd.Flag.StringVar(&buildContext.InstallSuffix, "installsuffix", "", "")
+	cmd.Flag.BoolVar(&buildV, "v", false, "")
+	cmd.Flag.BoolVar(&buildX, "x", false, "")
+	cmd.Flag.BoolVar(&buildWork, "work", false, "")
+	cmd.Flag.Var((*stringsFlag)(&buildGcflags), "gcflags", "")
+	cmd.Flag.Var((*stringsFlag)(&buildCcflags), "ccflags", "")
+	cmd.Flag.Var((*stringsFlag)(&buildLdflags), "ldflags", "")
+	cmd.Flag.Var((*stringsFlag)(&buildGccgoflags), "gccgoflags", "")
+	cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
+	cmd.Flag.Var(buildCompiler{}, "compiler", "")
+	cmd.Flag.BoolVar(&buildRace, "race", false, "")
+	switch build.Default.Compiler {
+	case "gc":
+		reqPkgSrc = true
+	case "gccgo":
+		reqPkgSrc = false
+	}
+}
+
+func addBuildFlagsNX(cmd *Command) {
+	cmd.Flag.BoolVar(&buildN, "n", false, "")
+	cmd.Flag.BoolVar(&buildX, "x", false, "")
+}
+
+func isSpaceByte(c byte) bool {
+	return c == ' ' || c == '\t' || c == '\n' || c == '\r'
+}
+
+// fileExtSplit expects a filename and returns the name
+// and ext (without the dot). If the file has no
+// extension, ext will be empty.
+func fileExtSplit(file string) (name, ext string) {
+	dotExt := filepath.Ext(file)
+	name = file[:len(file)-len(dotExt)]
+	if dotExt != "" {
+		ext = dotExt[1:]
+	}
+	return
+}
+
+type stringsFlag []string
+
+func (v *stringsFlag) Set(s string) error {
+	var err error
+	*v, err = splitQuotedFields(s)
+	if *v == nil {
+		*v = []string{}
+	}
+	return err
+}
+
+func splitQuotedFields(s string) ([]string, error) {
+	// Split fields allowing '' or "" around elements.
+	// Quotes further inside the string do not count.
+	var f []string
+	for len(s) > 0 {
+		for len(s) > 0 && isSpaceByte(s[0]) {
+			s = s[1:]
+		}
+		if len(s) == 0 {
+			break
+		}
+		// Accepted quoted string. No unescaping inside.
+		if s[0] == '"' || s[0] == '\'' {
+			quote := s[0]
+			s = s[1:]
+			i := 0
+			for i < len(s) && s[i] != quote {
+				i++
+			}
+			if i >= len(s) {
+				return nil, fmt.Errorf("unterminated %c string", quote)
+			}
+			f = append(f, s[:i])
+			s = s[i+1:]
+			continue
+		}
+		i := 0
+		for i < len(s) && !isSpaceByte(s[i]) {
+			i++
+		}
+		f = append(f, s[:i])
+		s = s[i:]
+	}
+	return f, nil
+}
+
+func (v *stringsFlag) String() string {
+	return "<stringsFlag>"
+}
+
+func runBuild(cmd *Command, args []string) {
+	raceInit()
+	var b builder
+	b.init()
+
+	pkgs := packagesForBuild(args)
+
+	if len(pkgs) == 1 && pkgs[0].Name == "main" && *buildO == "" {
+		_, *buildO = path.Split(pkgs[0].ImportPath)
+		*buildO += exeSuffix
+	}
+
+	// sanity check some often mis-used options
+	switch buildContext.Compiler {
+	case "gccgo":
+		if len(buildGcflags) != 0 {
+			fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags")
+		}
+		if len(buildLdflags) != 0 {
+			fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags")
+		}
+	case "gc":
+		if len(buildGccgoflags) != 0 {
+			fmt.Println("go build: when using gc toolchain, please pass compile flags using -gcflags, and linker flags using -ldflags")
+		}
+	}
+
+	if *buildO != "" {
+		if len(pkgs) > 1 {
+			fatalf("go build: cannot use -o with multiple packages")
+		}
+		p := pkgs[0]
+		p.target = "" // must build - not up to date
+		a := b.action(modeInstall, modeBuild, p)
+		a.target = *buildO
+		b.do(a)
+		return
+	}
+
+	a := &action{}
+	depMode := modeBuild
+	if buildI {
+		depMode = modeInstall
+	}
+	for _, p := range packages(args) {
+		a.deps = append(a.deps, b.action(modeBuild, depMode, p))
+	}
+	b.do(a)
+}
+
+var cmdInstall = &Command{
+	UsageLine: "install [build flags] [packages]",
+	Short:     "compile and install packages and dependencies",
+	Long: `
+Install compiles and installs the packages named by the import paths,
+along with their dependencies.
+
+For more about the build flags, see 'go help build'.
+For more about specifying packages, see 'go help packages'.
+
+See also: go build, go get, go clean.
+	`,
+}
+
+func runInstall(cmd *Command, args []string) {
+	raceInit()
+	pkgs := packagesForBuild(args)
+
+	for _, p := range pkgs {
+		if p.Target == "" && (!p.Standard || p.ImportPath != "unsafe") {
+			if p.cmdline {
+				errorf("go install: no install location for .go files listed on command line (GOBIN not set)")
+			} else if p.ConflictDir != "" {
+				errorf("go install: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
+			} else {
+				errorf("go install: no install location for directory %s outside GOPATH", p.Dir)
+			}
+		}
+	}
+	exitIfErrors()
+
+	var b builder
+	b.init()
+	a := &action{}
+	for _, p := range pkgs {
+		a.deps = append(a.deps, b.action(modeInstall, modeInstall, p))
+	}
+	b.do(a)
+}
+
+// Global build parameters (used during package load)
+var (
+	goarch    string
+	goos      string
+	archChar  string
+	exeSuffix string
+)
+
+func init() {
+	goarch = buildContext.GOARCH
+	goos = buildContext.GOOS
+	if goos == "windows" {
+		exeSuffix = ".exe"
+	}
+	var err error
+	archChar, err = build.ArchChar(goarch)
+	if err != nil {
+		if _, isgc := buildToolchain.(gcToolchain); isgc {
+			fatalf("%s", err)
+		}
+		// archChar is only required for gcToolchain, if we're using
+		// another toolchain leave it blank.
+		archChar = ""
+	}
+}
+
+// A builder holds global state about a build.
+// It does not hold per-package state, because we
+// build packages in parallel, and the builder is shared.
+type builder struct {
+	work        string               // the temporary work directory (ends in filepath.Separator)
+	actionCache map[cacheKey]*action // a cache of already-constructed actions
+	mkdirCache  map[string]bool      // a cache of created directories
+	print       func(args ...interface{}) (int, error)
+
+	output    sync.Mutex
+	scriptDir string // current directory in printed script
+
+	exec      sync.Mutex
+	readySema chan bool
+	ready     actionQueue
+}
+
+// An action represents a single action in the action graph.
+type action struct {
+	p          *Package      // the package this action works on
+	deps       []*action     // actions that must happen before this one
+	triggers   []*action     // inverse of deps
+	cgo        *action       // action for cgo binary if needed
+	args       []string      // additional args for runProgram
+	testOutput *bytes.Buffer // test output buffer
+
+	f          func(*builder, *action) error // the action itself (nil = no-op)
+	ignoreFail bool                          // whether to run f even if dependencies fail
+
+	// Generated files, directories.
+	link   bool   // target is executable, not just package
+	pkgdir string // the -I or -L argument to use when importing this package
+	objdir string // directory for intermediate objects
+	objpkg string // the intermediate package .a file created during the action
+	target string // goal of the action: the created package or executable
+
+	// Execution state.
+	pending  int  // number of deps yet to complete
+	priority int  // relative execution priority
+	failed   bool // whether the action failed
+}
+
+// cacheKey is the key for the action cache.
+type cacheKey struct {
+	mode buildMode
+	p    *Package
+}
+
+// buildMode specifies the build mode:
+// are we just building things or also installing the results?
+type buildMode int
+
+const (
+	modeBuild buildMode = iota
+	modeInstall
+)
+
+var (
+	goroot       = filepath.Clean(runtime.GOROOT())
+	gobin        = os.Getenv("GOBIN")
+	gorootBin    = filepath.Join(goroot, "bin")
+	gorootSrcPkg = filepath.Join(goroot, "src/pkg")
+	gorootPkg    = filepath.Join(goroot, "pkg")
+	gorootSrc    = filepath.Join(goroot, "src")
+)
+
+func (b *builder) init() {
+	var err error
+	b.print = func(a ...interface{}) (int, error) {
+		return fmt.Fprint(os.Stderr, a...)
+	}
+	b.actionCache = make(map[cacheKey]*action)
+	b.mkdirCache = make(map[string]bool)
+
+	if buildN {
+		b.work = "$WORK"
+	} else {
+		b.work, err = ioutil.TempDir("", "go-build")
+		if err != nil {
+			fatalf("%s", err)
+		}
+		if buildX || buildWork {
+			fmt.Fprintf(os.Stderr, "WORK=%s\n", b.work)
+		}
+		if !buildWork {
+			workdir := b.work
+			atexit(func() { os.RemoveAll(workdir) })
+		}
+	}
+}
+
+// goFilesPackage creates a package for building a collection of Go files
+// (typically named on the command line).  The target is named p.a for
+// package p or named after the first Go file for package main.
+func goFilesPackage(gofiles []string) *Package {
+	// TODO: Remove this restriction.
+	for _, f := range gofiles {
+		if !strings.HasSuffix(f, ".go") {
+			fatalf("named files must be .go files")
+		}
+	}
+
+	var stk importStack
+	ctxt := buildContext
+	ctxt.UseAllFiles = true
+
+	// Synthesize fake "directory" that only shows the named files,
+	// to make it look like this is a standard package or
+	// command directory.  So that local imports resolve
+	// consistently, the files must all be in the same directory.
+	var dirent []os.FileInfo
+	var dir string
+	for _, file := range gofiles {
+		fi, err := os.Stat(file)
+		if err != nil {
+			fatalf("%s", err)
+		}
+		if fi.IsDir() {
+			fatalf("%s is a directory, should be a Go file", file)
+		}
+		dir1, _ := filepath.Split(file)
+		if dir == "" {
+			dir = dir1
+		} else if dir != dir1 {
+			fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
+		}
+		dirent = append(dirent, fi)
+	}
+	ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
+
+	if !filepath.IsAbs(dir) {
+		dir = filepath.Join(cwd, dir)
+	}
+
+	bp, err := ctxt.ImportDir(dir, 0)
+	pkg := new(Package)
+	pkg.local = true
+	pkg.cmdline = true
+	pkg.load(&stk, bp, err)
+	pkg.localPrefix = dirToImportPath(dir)
+	pkg.ImportPath = "command-line-arguments"
+	pkg.target = ""
+
+	if pkg.Name == "main" {
+		_, elem := filepath.Split(gofiles[0])
+		exe := elem[:len(elem)-len(".go")] + exeSuffix
+		if *buildO == "" {
+			*buildO = exe
+		}
+		if gobin != "" {
+			pkg.target = filepath.Join(gobin, exe)
+		}
+	} else {
+		if *buildO == "" {
+			*buildO = pkg.Name + ".a"
+		}
+	}
+	pkg.Target = pkg.target
+	pkg.Stale = true
+
+	computeStale(pkg)
+	return pkg
+}
+
+// action returns the action for applying the given operation (mode) to the package.
+// depMode is the action to use when building dependencies.
+func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action {
+	key := cacheKey{mode, p}
+	a := b.actionCache[key]
+	if a != nil {
+		return a
+	}
+
+	a = &action{p: p, pkgdir: p.build.PkgRoot}
+	if p.pkgdir != "" { // overrides p.t
+		a.pkgdir = p.pkgdir
+	}
+
+	b.actionCache[key] = a
+
+	for _, p1 := range p.imports {
+		a.deps = append(a.deps, b.action(depMode, depMode, p1))
+	}
+
+	// If we are not doing a cross-build, then record the binary we'll
+	// generate for cgo as a dependency of the build of any package
+	// using cgo, to make sure we do not overwrite the binary while
+	// a package is using it.  If this is a cross-build, then the cgo we
+	// are writing is not the cgo we need to use.
+
+	if goos == runtime.GOOS && goarch == runtime.GOARCH && !buildRace {
+		if reqPkgSrc {
+			if len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo" {
+				var stk importStack
+				p1 := loadPackage("cmd/cgo", &stk)
+				if p1.Error != nil {
+					fatalf("load cmd/cgo: %v", p1.Error)
+				}
+				a.cgo = b.action(depMode, depMode, p1)
+				a.deps = append(a.deps, a.cgo)
+			}
+		}
+	}
+
+	if p.Standard {
+		switch p.ImportPath {
+		case "builtin", "unsafe":
+			// Fake packages - nothing to build.
+			return a
+		}
+		// gccgo standard library is "fake" too.
+		if _, ok := buildToolchain.(gccgoToolchain); ok {
+			// the target name is needed for cgo.
+			a.target = p.target
+			return a
+		}
+	}
+
+	if !p.Stale && p.target != "" {
+		// p.Stale==false implies that p.target is up-to-date.
+		// Record target name for use by actions depending on this one.
+		a.target = p.target
+		return a
+	}
+
+	if p.local && p.target == "" {
+		// Imported via local path.  No permanent target.
+		mode = modeBuild
+	}
+	work := p.pkgdir
+	if work == "" {
+		work = b.work
+	}
+	a.objdir = filepath.Join(work, a.p.ImportPath, "_obj") + string(filepath.Separator)
+	a.objpkg = buildToolchain.pkgpath(work, a.p)
+	a.link = p.Name == "main"
+
+	switch mode {
+	case modeInstall:
+		a.f = (*builder).install
+		a.deps = []*action{b.action(modeBuild, depMode, p)}
+		a.target = a.p.target
+	case modeBuild:
+		a.f = (*builder).build
+		a.target = a.objpkg
+		if a.link {
+			// An executable file. (This is the name of a temporary file.)
+			// Because we run the temporary file in 'go run' and 'go test',
+			// the name will show up in ps listings. If the caller has specified
+			// a name, use that instead of a.out. The binary is generated
+			// in an otherwise empty subdirectory named exe to avoid
+			// naming conflicts.  The only possible conflict is if we were
+			// to create a top-level package named exe.
+			name := "a.out"
+			if p.exeName != "" {
+				name = p.exeName
+			}
+			a.target = a.objdir + filepath.Join("exe", name) + exeSuffix
+		}
+	}
+
+	return a
+}
+
+// actionList returns the list of actions in the dag rooted at root
+// as visited in a depth-first post-order traversal.
+func actionList(root *action) []*action {
+	seen := map[*action]bool{}
+	all := []*action{}
+	var walk func(*action)
+	walk = func(a *action) {
+		if seen[a] {
+			return
+		}
+		seen[a] = true
+		for _, a1 := range a.deps {
+			walk(a1)
+		}
+		all = append(all, a)
+	}
+	walk(root)
+	return all
+}
+
+// do runs the action graph rooted at root.
+func (b *builder) do(root *action) {
+	// Build list of all actions, assigning depth-first post-order priority.
+	// The original implementation here was a true queue
+	// (using a channel) but it had the effect of getting
+	// distracted by low-level leaf actions to the detriment
+	// of completing higher-level actions.  The order of
+	// work does not matter much to overall execution time,
+	// but when running "go test std" it is nice to see each test
+	// results as soon as possible.  The priorities assigned
+	// ensure that, all else being equal, the execution prefers
+	// to do what it would have done first in a simple depth-first
+	// dependency order traversal.
+	all := actionList(root)
+	for i, a := range all {
+		a.priority = i
+	}
+
+	b.readySema = make(chan bool, len(all))
+
+	// Initialize per-action execution state.
+	for _, a := range all {
+		for _, a1 := range a.deps {
+			a1.triggers = append(a1.triggers, a)
+		}
+		a.pending = len(a.deps)
+		if a.pending == 0 {
+			b.ready.push(a)
+			b.readySema <- true
+		}
+	}
+
+	// Handle runs a single action and takes care of triggering
+	// any actions that are runnable as a result.
+	handle := func(a *action) {
+		var err error
+		if a.f != nil && (!a.failed || a.ignoreFail) {
+			err = a.f(b, a)
+		}
+
+		// The actions run in parallel but all the updates to the
+		// shared work state are serialized through b.exec.
+		b.exec.Lock()
+		defer b.exec.Unlock()
+
+		if err != nil {
+			if err == errPrintedOutput {
+				setExitStatus(2)
+			} else {
+				errorf("%s", err)
+			}
+			a.failed = true
+		}
+
+		for _, a0 := range a.triggers {
+			if a.failed {
+				a0.failed = true
+			}
+			if a0.pending--; a0.pending == 0 {
+				b.ready.push(a0)
+				b.readySema <- true
+			}
+		}
+
+		if a == root {
+			close(b.readySema)
+		}
+	}
+
+	var wg sync.WaitGroup
+
+	// Kick off goroutines according to parallelism.
+	// If we are using the -n flag (just printing commands)
+	// drop the parallelism to 1, both to make the output
+	// deterministic and because there is no real work anyway.
+	par := buildP
+	if buildN {
+		par = 1
+	}
+	for i := 0; i < par; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			for {
+				select {
+				case _, ok := <-b.readySema:
+					if !ok {
+						return
+					}
+					// Receiving a value from b.readySema entitles
+					// us to take from the ready queue.
+					b.exec.Lock()
+					a := b.ready.pop()
+					b.exec.Unlock()
+					handle(a)
+				case <-interrupted:
+					setExitStatus(1)
+					return
+				}
+			}
+		}()
+	}
+
+	wg.Wait()
+}
+
+// hasString reports whether s appears in the list of strings.
+func hasString(strings []string, s string) bool {
+	for _, t := range strings {
+		if s == t {
+			return true
+		}
+	}
+	return false
+}
+
+// build is the action for building a single package or command.
+func (b *builder) build(a *action) (err error) {
+	// Return an error if the package has CXX files but it's not using
+	// cgo nor SWIG, since the CXX files can only be processed by cgo
+	// and SWIG (it's possible to have packages with C files without
+	// using cgo, they will get compiled with the plan9 C compiler and
+	// linked with the rest of the package).
+	if len(a.p.CXXFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
+		return fmt.Errorf("can't build package %s because it contains C++ files (%s) but it's not using cgo nor SWIG",
+			a.p.ImportPath, strings.Join(a.p.CXXFiles, ","))
+	}
+	// Same as above for Objective-C files
+	if len(a.p.MFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
+		return fmt.Errorf("can't build package %s because it contains Objective-C files (%s) but it's not using cgo nor SWIG",
+			a.p.ImportPath, strings.Join(a.p.MFiles, ","))
+	}
+	defer func() {
+		if err != nil && err != errPrintedOutput {
+			err = fmt.Errorf("go build %s: %v", a.p.ImportPath, err)
+		}
+	}()
+	if buildN {
+		// In -n mode, print a banner between packages.
+		// The banner is five lines so that when changes to
+		// different sections of the bootstrap script have to
+		// be merged, the banners give patch something
+		// to use to find its context.
+		fmt.Printf("\n#\n# %s\n#\n\n", a.p.ImportPath)
+	}
+
+	if buildV {
+		fmt.Fprintf(os.Stderr, "%s\n", a.p.ImportPath)
+	}
+
+	if a.p.Standard && a.p.ImportPath == "runtime" && buildContext.Compiler == "gc" &&
+		!hasString(a.p.HFiles, "zasm_"+buildContext.GOOS+"_"+buildContext.GOARCH+".h") {
+		return fmt.Errorf("%s/%s must be bootstrapped using make%v", buildContext.GOOS, buildContext.GOARCH, defaultSuffix())
+	}
+
+	// Make build directory.
+	obj := a.objdir
+	if err := b.mkdir(obj); err != nil {
+		return err
+	}
+
+	// make target directory
+	dir, _ := filepath.Split(a.target)
+	if dir != "" {
+		if err := b.mkdir(dir); err != nil {
+			return err
+		}
+	}
+
+	var gofiles, cfiles, sfiles, objects, cgoObjects []string
+
+	gofiles = append(gofiles, a.p.GoFiles...)
+	cfiles = append(cfiles, a.p.CFiles...)
+	sfiles = append(sfiles, a.p.SFiles...)
+
+	// Run cgo.
+	if a.p.usesCgo() {
+		// In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
+		// There is one exception: runtime/cgo's job is to bridge the
+		// cgo and non-cgo worlds, so it necessarily has files in both.
+		// In that case gcc only gets the gcc_* files.
+		var gccfiles []string
+		if a.p.Standard && a.p.ImportPath == "runtime/cgo" {
+			filter := func(files, nongcc, gcc []string) ([]string, []string) {
+				for _, f := range files {
+					if strings.HasPrefix(f, "gcc_") {
+						gcc = append(gcc, f)
+					} else {
+						nongcc = append(nongcc, f)
+					}
+				}
+				return nongcc, gcc
+			}
+			cfiles, gccfiles = filter(cfiles, cfiles[:0], gccfiles)
+			sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
+		} else {
+			gccfiles = append(cfiles, sfiles...)
+			cfiles = nil
+			sfiles = nil
+		}
+
+		cgoExe := tool("cgo")
+		if a.cgo != nil && a.cgo.target != "" {
+			cgoExe = a.cgo.target
+		}
+		outGo, outObj, err := b.cgo(a.p, cgoExe, obj, gccfiles, a.p.CXXFiles, a.p.MFiles)
+		if err != nil {
+			return err
+		}
+		cgoObjects = append(cgoObjects, outObj...)
+		gofiles = append(gofiles, outGo...)
+	}
+
+	// Run SWIG.
+	if a.p.usesSwig() {
+		// In a package using SWIG, any .c or .s files are
+		// compiled with gcc.
+		gccfiles := append(cfiles, sfiles...)
+		cfiles = nil
+		sfiles = nil
+		outGo, outObj, err := b.swig(a.p, obj, gccfiles, a.p.CXXFiles, a.p.MFiles)
+		if err != nil {
+			return err
+		}
+		cgoObjects = append(cgoObjects, outObj...)
+		gofiles = append(gofiles, outGo...)
+	}
+
+	if len(gofiles) == 0 {
+		return &build.NoGoError{a.p.Dir}
+	}
+
+	// If we're doing coverage, preprocess the .go files and put them in the work directory
+	if a.p.coverMode != "" {
+		for i, file := range gofiles {
+			var sourceFile string
+			var coverFile string
+			var key string
+			if strings.HasSuffix(file, ".cgo1.go") {
+				// cgo files have absolute paths
+				base := filepath.Base(file)
+				sourceFile = file
+				coverFile = filepath.Join(obj, base)
+				key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
+			} else {
+				sourceFile = filepath.Join(a.p.Dir, file)
+				coverFile = filepath.Join(obj, file)
+				key = file
+			}
+			cover := a.p.coverVars[key]
+			if cover == nil || isTestFile(file) {
+				// Not covering this file.
+				continue
+			}
+			if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
+				return err
+			}
+			gofiles[i] = coverFile
+		}
+	}
+
+	// Prepare Go import path list.
+	inc := b.includeArgs("-I", a.deps)
+
+	// Compile Go.
+	ofile, out, err := buildToolchain.gc(b, a.p, a.objpkg, obj, inc, gofiles)
+	if len(out) > 0 {
+		b.showOutput(a.p.Dir, a.p.ImportPath, b.processOutput(out))
+		if err != nil {
+			return errPrintedOutput
+		}
+	}
+	if err != nil {
+		return err
+	}
+	if ofile != a.objpkg {
+		objects = append(objects, ofile)
+	}
+
+	// Copy .h files named for goos or goarch or goos_goarch
+	// to names using GOOS and GOARCH.
+	// For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
+	_goos_goarch := "_" + goos + "_" + goarch
+	_goos := "_" + goos
+	_goarch := "_" + goarch
+	for _, file := range a.p.HFiles {
+		name, ext := fileExtSplit(file)
+		switch {
+		case strings.HasSuffix(name, _goos_goarch):
+			targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
+			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
+				return err
+			}
+		case strings.HasSuffix(name, _goarch):
+			targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
+			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
+				return err
+			}
+		case strings.HasSuffix(name, _goos):
+			targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
+			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
+				return err
+			}
+		}
+	}
+
+	objExt := archChar
+	if _, ok := buildToolchain.(gccgoToolchain); ok {
+		objExt = "o"
+	}
+
+	for _, file := range cfiles {
+		out := file[:len(file)-len(".c")] + "." + objExt
+		if err := buildToolchain.cc(b, a.p, obj, obj+out, file); err != nil {
+			return err
+		}
+		objects = append(objects, out)
+	}
+
+	// Assemble .s files.
+	for _, file := range sfiles {
+		out := file[:len(file)-len(".s")] + "." + objExt
+		if err := buildToolchain.asm(b, a.p, obj, obj+out, file); err != nil {
+			return err
+		}
+		objects = append(objects, out)
+	}
+
+	// NOTE(rsc): On Windows, it is critically important that the
+	// gcc-compiled objects (cgoObjects) be listed after the ordinary
+	// objects in the archive.  I do not know why this is.
+	// http://golang.org/issue/2601
+	objects = append(objects, cgoObjects...)
+
+	// Add system object files.
+	for _, syso := range a.p.SysoFiles {
+		objects = append(objects, filepath.Join(a.p.Dir, syso))
+	}
+
+	// Pack into archive in obj directory.
+	// If the Go compiler wrote an archive, we only need to add the
+	// object files for non-Go sources to the archive.
+	// If the Go compiler wrote an archive and the package is entirely
+	// Go sources, there is no pack to execute at all.
+	if len(objects) > 0 {
+		if err := buildToolchain.pack(b, a.p, obj, a.objpkg, objects); err != nil {
+			return err
+		}
+	}
+
+	// Link if needed.
+	if a.link {
+		// The compiler only cares about direct imports, but the
+		// linker needs the whole dependency tree.
+		all := actionList(a)
+		all = all[:len(all)-1] // drop a
+		if err := buildToolchain.ld(b, a.p, a.target, all, a.objpkg, objects); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// install is the action for installing a single package or executable.
+func (b *builder) install(a *action) (err error) {
+	defer func() {
+		if err != nil && err != errPrintedOutput {
+			err = fmt.Errorf("go install %s: %v", a.p.ImportPath, err)
+		}
+	}()
+	a1 := a.deps[0]
+	perm := os.FileMode(0644)
+	if a1.link {
+		perm = 0755
+	}
+
+	// make target directory
+	dir, _ := filepath.Split(a.target)
+	if dir != "" {
+		if err := b.mkdir(dir); err != nil {
+			return err
+		}
+	}
+
+	// remove object dir to keep the amount of
+	// garbage down in a large build.  On an operating system
+	// with aggressive buffering, cleaning incrementally like
+	// this keeps the intermediate objects from hitting the disk.
+	if !buildWork {
+		defer os.RemoveAll(a1.objdir)
+		defer os.Remove(a1.target)
+	}
+
+	return b.moveOrCopyFile(a, a.target, a1.target, perm)
+}
+
+// includeArgs returns the -I or -L directory list for access
+// to the results of the list of actions.
+func (b *builder) includeArgs(flag string, all []*action) []string {
+	inc := []string{}
+	incMap := map[string]bool{
+		b.work:    true, // handled later
+		gorootPkg: true,
+		"":        true, // ignore empty strings
+	}
+
+	// Look in the temporary space for results of test-specific actions.
+	// This is the $WORK/my/package/_test directory for the
+	// package being built, so there are few of these.
+	for _, a1 := range all {
+		if dir := a1.pkgdir; dir != a1.p.build.PkgRoot && !incMap[dir] {
+			incMap[dir] = true
+			inc = append(inc, flag, dir)
+		}
+	}
+
+	// Also look in $WORK for any non-test packages that have
+	// been built but not installed.
+	inc = append(inc, flag, b.work)
+
+	// Finally, look in the installed package directories for each action.
+	for _, a1 := range all {
+		if dir := a1.pkgdir; dir == a1.p.build.PkgRoot && !incMap[dir] {
+			incMap[dir] = true
+			if _, ok := buildToolchain.(gccgoToolchain); ok {
+				dir = filepath.Join(dir, "gccgo_"+goos+"_"+goarch)
+			} else {
+				dir = filepath.Join(dir, goos+"_"+goarch)
+				if buildContext.InstallSuffix != "" {
+					dir += "_" + buildContext.InstallSuffix
+				}
+			}
+			inc = append(inc, flag, dir)
+		}
+	}
+
+	return inc
+}
+
+// moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
+func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode) error {
+	if buildN {
+		b.showcmd("", "mv %s %s", src, dst)
+		return nil
+	}
+
+	// If we can update the mode and rename to the dst, do it.
+	// Otherwise fall back to standard copy.
+	if err := os.Chmod(src, perm); err == nil {
+		if err := os.Rename(src, dst); err == nil {
+			if buildX {
+				b.showcmd("", "mv %s %s", src, dst)
+			}
+			return nil
+		}
+	}
+
+	return b.copyFile(a, dst, src, perm)
+}
+
+// copyFile is like 'cp src dst'.
+func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode) error {
+	if buildN || buildX {
+		b.showcmd("", "cp %s %s", src, dst)
+		if buildN {
+			return nil
+		}
+	}
+
+	sf, err := os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer sf.Close()
+
+	// Be careful about removing/overwriting dst.
+	// Do not remove/overwrite if dst exists and is a directory
+	// or a non-object file.
+	if fi, err := os.Stat(dst); err == nil {
+		if fi.IsDir() {
+			return fmt.Errorf("build output %q already exists and is a directory", dst)
+		}
+		if !isObject(dst) {
+			return fmt.Errorf("build output %q already exists and is not an object file", dst)
+		}
+	}
+
+	// On Windows, remove lingering ~ file from last attempt.
+	if toolIsWindows {
+		if _, err := os.Stat(dst + "~"); err == nil {
+			os.Remove(dst + "~")
+		}
+	}
+
+	os.Remove(dst)
+	df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
+	if err != nil && toolIsWindows {
+		// Windows does not allow deletion of a binary file
+		// while it is executing.  Try to move it out of the way.
+		// If the move fails, which is likely, we'll try again the
+		// next time we do an install of this binary.
+		if err := os.Rename(dst, dst+"~"); err == nil {
+			os.Remove(dst + "~")
+		}
+		df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
+	}
+	if err != nil {
+		return err
+	}
+
+	_, err = io.Copy(df, sf)
+	df.Close()
+	if err != nil {
+		os.Remove(dst)
+		return fmt.Errorf("copying %s to %s: %v", src, dst, err)
+	}
+	return nil
+}
+
+// cover runs, in effect,
+//	go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
+func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error {
+	return b.run(a.objdir, "cover "+a.p.ImportPath, nil,
+		tool("cover"),
+		"-mode", a.p.coverMode,
+		"-var", varName,
+		"-o", dst,
+		src)
+}
+
+var objectMagic = [][]byte{
+	{'!', '<', 'a', 'r', 'c', 'h', '>', '\n'},        // Package archive
+	{'\x7F', 'E', 'L', 'F'},                          // ELF
+	{0xFE, 0xED, 0xFA, 0xCE},                         // Mach-O big-endian 32-bit
+	{0xFE, 0xED, 0xFA, 0xCF},                         // Mach-O big-endian 64-bit
+	{0xCE, 0xFA, 0xED, 0xFE},                         // Mach-O little-endian 32-bit
+	{0xCF, 0xFA, 0xED, 0xFE},                         // Mach-O little-endian 64-bit
+	{0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x04, 0x00}, // PE (Windows) as generated by 6l/8l
+	{0x00, 0x00, 0x01, 0xEB},                         // Plan 9 i386
+	{0x00, 0x00, 0x8a, 0x97},                         // Plan 9 amd64
+}
+
+func isObject(s string) bool {
+	f, err := os.Open(s)
+	if err != nil {
+		return false
+	}
+	defer f.Close()
+	buf := make([]byte, 64)
+	io.ReadFull(f, buf)
+	for _, magic := range objectMagic {
+		if bytes.HasPrefix(buf, magic) {
+			return true
+		}
+	}
+	return false
+}
+
+// fmtcmd formats a command in the manner of fmt.Sprintf but also:
+//
+//	If dir is non-empty and the script is not in dir right now,
+//	fmtcmd inserts "cd dir\n" before the command.
+//
+//	fmtcmd replaces the value of b.work with $WORK.
+//	fmtcmd replaces the value of goroot with $GOROOT.
+//	fmtcmd replaces the value of b.gobin with $GOBIN.
+//
+//	fmtcmd replaces the name of the current directory with dot (.)
+//	but only when it is at the beginning of a space-separated token.
+//
+func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string {
+	cmd := fmt.Sprintf(format, args...)
+	if dir != "" && dir != "/" {
+		cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:]
+		if b.scriptDir != dir {
+			b.scriptDir = dir
+			cmd = "cd " + dir + "\n" + cmd
+		}
+	}
+	if b.work != "" {
+		cmd = strings.Replace(cmd, b.work, "$WORK", -1)
+	}
+	return cmd
+}
+
+// showcmd prints the given command to standard output
+// for the implementation of -n or -x.
+func (b *builder) showcmd(dir string, format string, args ...interface{}) {
+	b.output.Lock()
+	defer b.output.Unlock()
+	b.print(b.fmtcmd(dir, format, args...) + "\n")
+}
+
+// showOutput prints "# desc" followed by the given output.
+// The output is expected to contain references to 'dir', usually
+// the source directory for the package that has failed to build.
+// showOutput rewrites mentions of dir with a relative path to dir
+// when the relative path is shorter.  This is usually more pleasant.
+// For example, if fmt doesn't compile and we are in src/pkg/html,
+// the output is
+//
+//	$ go build
+//	# fmt
+//	../fmt/print.go:1090: undefined: asdf
+//	$
+//
+// instead of
+//
+//	$ go build
+//	# fmt
+//	/usr/gopher/go/src/pkg/fmt/print.go:1090: undefined: asdf
+//	$
+//
+// showOutput also replaces references to the work directory with $WORK.
+//
+func (b *builder) showOutput(dir, desc, out string) {
+	prefix := "# " + desc
+	suffix := "\n" + out
+	if reldir := shortPath(dir); reldir != dir {
+		suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
+		suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
+	}
+	suffix = strings.Replace(suffix, " "+b.work, " $WORK", -1)
+
+	b.output.Lock()
+	defer b.output.Unlock()
+	b.print(prefix, suffix)
+}
+
+// shortPath returns an absolute or relative name for path, whatever is shorter.
+func shortPath(path string) string {
+	if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
+		return rel
+	}
+	return path
+}
+
+// relPaths returns a copy of paths with absolute paths
+// made relative to the current directory if they would be shorter.
+func relPaths(paths []string) []string {
+	var out []string
+	pwd, _ := os.Getwd()
+	for _, p := range paths {
+		rel, err := filepath.Rel(pwd, p)
+		if err == nil && len(rel) < len(p) {
+			p = rel
+		}
+		out = append(out, p)
+	}
+	return out
+}
+
+// errPrintedOutput is a special error indicating that a command failed
+// but that it generated output as well, and that output has already
+// been printed, so there's no point showing 'exit status 1' or whatever
+// the wait status was.  The main executor, builder.do, knows not to
+// print this error.
+var errPrintedOutput = errors.New("already printed output - no need to show error")
+
+var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.cgo1\.go:[0-9]+\]`)
+var cgoTypeSigRe = regexp.MustCompile(`\b_Ctype_\B`)
+
+// run runs the command given by cmdline in the directory dir.
+// If the command fails, run prints information about the failure
+// and returns a non-nil error.
+func (b *builder) run(dir string, desc string, env []string, cmdargs ...interface{}) error {
+	out, err := b.runOut(dir, desc, env, cmdargs...)
+	if len(out) > 0 {
+		if desc == "" {
+			desc = b.fmtcmd(dir, "%s", strings.Join(stringList(cmdargs...), " "))
+		}
+		b.showOutput(dir, desc, b.processOutput(out))
+		if err != nil {
+			err = errPrintedOutput
+		}
+	}
+	return err
+}
+
+// processOutput prepares the output of runOut to be output to the console.
+func (b *builder) processOutput(out []byte) string {
+	if out[len(out)-1] != '\n' {
+		out = append(out, '\n')
+	}
+	messages := string(out)
+	// Fix up output referring to cgo-generated code to be more readable.
+	// Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
+	// Replace *[100]_Ctype_foo with *[100]C.foo.
+	// If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
+	if !buildX && cgoLine.MatchString(messages) {
+		messages = cgoLine.ReplaceAllString(messages, "")
+		messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
+	}
+	return messages
+}
+
+// runOut runs the command given by cmdline in the directory dir.
+// It returns the command output and any errors that occurred.
+func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
+	cmdline := stringList(cmdargs...)
+	if buildN || buildX {
+		var envcmdline string
+		for i := range env {
+			envcmdline += env[i]
+			envcmdline += " "
+		}
+		envcmdline += joinUnambiguously(cmdline)
+		b.showcmd(dir, "%s", envcmdline)
+		if buildN {
+			return nil, nil
+		}
+	}
+
+	nbusy := 0
+	for {
+		var buf bytes.Buffer
+		cmd := exec.Command(cmdline[0], cmdline[1:]...)
+		cmd.Stdout = &buf
+		cmd.Stderr = &buf
+		cmd.Dir = dir
+		cmd.Env = mergeEnvLists(env, envForDir(cmd.Dir))
+		err := cmd.Run()
+
+		// cmd.Run will fail on Unix if some other process has the binary
+		// we want to run open for writing.  This can happen here because
+		// we build and install the cgo command and then run it.
+		// If another command was kicked off while we were writing the
+		// cgo binary, the child process for that command may be holding
+		// a reference to the fd, keeping us from running exec.
+		//
+		// But, you might reasonably wonder, how can this happen?
+		// The cgo fd, like all our fds, is close-on-exec, so that we need
+		// not worry about other processes inheriting the fd accidentally.
+		// The answer is that running a command is fork and exec.
+		// A child forked while the cgo fd is open inherits that fd.
+		// Until the child has called exec, it holds the fd open and the
+		// kernel will not let us run cgo.  Even if the child were to close
+		// the fd explicitly, it would still be open from the time of the fork
+		// until the time of the explicit close, and the race would remain.
+		//
+		// On Unix systems, this results in ETXTBSY, which formats
+		// as "text file busy".  Rather than hard-code specific error cases,
+		// we just look for that string.  If this happens, sleep a little
+		// and try again.  We let this happen three times, with increasing
+		// sleep lengths: 100+200+400 ms = 0.7 seconds.
+		//
+		// An alternate solution might be to split the cmd.Run into
+		// separate cmd.Start and cmd.Wait, and then use an RWLock
+		// to make sure that copyFile only executes when no cmd.Start
+		// call is in progress.  However, cmd.Start (really syscall.forkExec)
+		// only guarantees that when it returns, the exec is committed to
+		// happen and succeed.  It uses a close-on-exec file descriptor
+		// itself to determine this, so we know that when cmd.Start returns,
+		// at least one close-on-exec file descriptor has been closed.
+		// However, we cannot be sure that all of them have been closed,
+		// so the program might still encounter ETXTBSY even with such
+		// an RWLock.  The race window would be smaller, perhaps, but not
+		// guaranteed to be gone.
+		//
+		// Sleeping when we observe the race seems to be the most reliable
+		// option we have.
+		//
+		// http://golang.org/issue/3001
+		//
+		if err != nil && nbusy < 3 && strings.Contains(err.Error(), "text file busy") {
+			time.Sleep(100 * time.Millisecond << uint(nbusy))
+			nbusy++
+			continue
+		}
+
+		return buf.Bytes(), err
+	}
+}
+
+// joinUnambiguously prints the slice, quoting where necessary to make the
+// output unambiguous.
+// TODO: See issue 5279. The printing of commands needs a complete redo.
+func joinUnambiguously(a []string) string {
+	var buf bytes.Buffer
+	for i, s := range a {
+		if i > 0 {
+			buf.WriteByte(' ')
+		}
+		q := strconv.Quote(s)
+		if s == "" || strings.Contains(s, " ") || len(q) > len(s)+2 {
+			buf.WriteString(q)
+		} else {
+			buf.WriteString(s)
+		}
+	}
+	return buf.String()
+}
+
+// mkdir makes the named directory.
+func (b *builder) mkdir(dir string) error {
+	b.exec.Lock()
+	defer b.exec.Unlock()
+	// We can be a little aggressive about being
+	// sure directories exist.  Skip repeated calls.
+	if b.mkdirCache[dir] {
+		return nil
+	}
+	b.mkdirCache[dir] = true
+
+	if buildN || buildX {
+		b.showcmd("", "mkdir -p %s", dir)
+		if buildN {
+			return nil
+		}
+	}
+
+	if err := os.MkdirAll(dir, 0777); err != nil {
+		return err
+	}
+	return nil
+}
+
+// mkAbs returns an absolute path corresponding to
+// evaluating f in the directory dir.
+// We always pass absolute paths of source files so that
+// the error messages will include the full path to a file
+// in need of attention.
+func mkAbs(dir, f string) string {
+	// Leave absolute paths alone.
+	// Also, during -n mode we use the pseudo-directory $WORK
+	// instead of creating an actual work directory that won't be used.
+	// Leave paths beginning with $WORK alone too.
+	if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") {
+		return f
+	}
+	return filepath.Join(dir, f)
+}
+
+type toolchain interface {
+	// gc runs the compiler in a specific directory on a set of files
+	// and returns the name of the generated output file.
+	// The compiler runs in the directory dir.
+	gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
+	// cc runs the toolchain's C compiler in a directory on a C file
+	// to produce an output file.
+	cc(b *builder, p *Package, objdir, ofile, cfile string) error
+	// asm runs the assembler in a specific directory on a specific file
+	// to generate the named output file.
+	asm(b *builder, p *Package, obj, ofile, sfile string) error
+	// pkgpath builds an appropriate path for a temporary package file.
+	pkgpath(basedir string, p *Package) string
+	// pack runs the archive packer in a specific directory to create
+	// an archive from a set of object files.
+	// typically it is run in the object directory.
+	pack(b *builder, p *Package, objDir, afile string, ofiles []string) error
+	// ld runs the linker to create a package starting at mainpkg.
+	ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error
+
+	compiler() string
+	linker() string
+}
+
+type noToolchain struct{}
+
+func noCompiler() error {
+	log.Fatalf("unknown compiler %q", buildContext.Compiler)
+	return nil
+}
+
+func (noToolchain) compiler() string {
+	noCompiler()
+	return ""
+}
+
+func (noToolchain) linker() string {
+	noCompiler()
+	return ""
+}
+
+func (noToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
+	return "", nil, noCompiler()
+}
+
+func (noToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
+	return noCompiler()
+}
+
+func (noToolchain) pkgpath(basedir string, p *Package) string {
+	noCompiler()
+	return ""
+}
+
+func (noToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
+	return noCompiler()
+}
+
+func (noToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
+	return noCompiler()
+}
+
+func (noToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
+	return noCompiler()
+}
+
+// The Go toolchain.
+type gcToolchain struct{}
+
+func (gcToolchain) compiler() string {
+	return tool(archChar + "g")
+}
+
+func (gcToolchain) linker() string {
+	return tool(archChar + "l")
+}
+
+func (gcToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
+	if archive != "" {
+		ofile = archive
+	} else {
+		out := "_go_." + archChar
+		ofile = obj + out
+	}
+
+	gcargs := []string{"-p", p.ImportPath}
+	if p.Standard && p.ImportPath == "runtime" {
+		// runtime compiles with a special 6g flag to emit
+		// additional reflect type data.
+		gcargs = append(gcargs, "-+")
+	}
+
+	// If we're giving the compiler the entire package (no C etc files), tell it that,
+	// so that it can give good error messages about forward declarations.
+	// Exceptions: a few standard packages have forward declarations for
+	// pieces supplied behind-the-scenes by package runtime.
+	extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.MFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles)
+	if p.Standard {
+		switch p.ImportPath {
+		case "os", "runtime/pprof", "sync", "time":
+			extFiles++
+		}
+	}
+	if extFiles == 0 {
+		gcargs = append(gcargs, "-complete")
+	}
+	if buildContext.InstallSuffix != "" {
+		gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix)
+	}
+
+	args := stringList(tool(archChar+"g"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs)
+	if ofile == archive {
+		args = append(args, "-pack")
+	}
+	for _, f := range gofiles {
+		args = append(args, mkAbs(p.Dir, f))
+	}
+
+	output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
+	return ofile, output, err
+}
+
+func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
+	sfile = mkAbs(p.Dir, sfile)
+	return b.run(p.Dir, p.ImportPath, nil, tool(archChar+"a"), "-trimpath", b.work, "-I", obj, "-o", ofile, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, sfile)
+}
+
+func (gcToolchain) pkgpath(basedir string, p *Package) string {
+	end := filepath.FromSlash(p.ImportPath + ".a")
+	return filepath.Join(basedir, end)
+}
+
+func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
+	var absOfiles []string
+	for _, f := range ofiles {
+		absOfiles = append(absOfiles, mkAbs(objDir, f))
+	}
+	cmd := "c"
+	absAfile := mkAbs(objDir, afile)
+	appending := false
+	if _, err := os.Stat(absAfile); err == nil {
+		appending = true
+		cmd = "r"
+	}
+
+	cmdline := stringList("pack", cmd, absAfile, absOfiles)
+
+	if appending {
+		if buildN || buildX {
+			b.showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
+		}
+		if buildN {
+			return nil
+		}
+		if err := packInternal(b, absAfile, absOfiles); err != nil {
+			b.showOutput(p.Dir, p.ImportPath, err.Error()+"\n")
+			return errPrintedOutput
+		}
+		return nil
+	}
+
+	// Need actual pack.
+	cmdline[0] = tool("pack")
+	return b.run(p.Dir, p.ImportPath, nil, cmdline)
+}
+
+func packInternal(b *builder, afile string, ofiles []string) error {
+	dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0)
+	if err != nil {
+		return err
+	}
+	defer dst.Close() // only for error returns or panics
+	w := bufio.NewWriter(dst)
+
+	for _, ofile := range ofiles {
+		src, err := os.Open(ofile)
+		if err != nil {
+			return err
+		}
+		fi, err := src.Stat()
+		if err != nil {
+			src.Close()
+			return err
+		}
+		// Note: Not using %-16.16s format because we care
+		// about bytes, not runes.
+		name := fi.Name()
+		if len(name) > 16 {
+			name = name[:16]
+		} else {
+			name += strings.Repeat(" ", 16-len(name))
+		}
+		size := fi.Size()
+		fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n",
+			name, 0, 0, 0, 0644, size)
+		n, err := io.Copy(w, src)
+		src.Close()
+		if err == nil && n < size {
+			err = io.ErrUnexpectedEOF
+		} else if err == nil && n > size {
+			err = fmt.Errorf("file larger than size reported by stat")
+		}
+		if err != nil {
+			return fmt.Errorf("copying %s to %s: %v", ofile, afile, err)
+		}
+		if size&1 != 0 {
+			w.WriteByte(0)
+		}
+	}
+
+	if err := w.Flush(); err != nil {
+		return err
+	}
+	return dst.Close()
+}
+
+func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
+	importArgs := b.includeArgs("-L", allactions)
+	cxx := false
+	for _, a := range allactions {
+		if a.p != nil && len(a.p.CXXFiles) > 0 {
+			cxx = true
+		}
+	}
+	ldflags := buildLdflags
+	// Limit slice capacity so that concurrent appends do not race on the shared array.
+	ldflags = ldflags[:len(ldflags):len(ldflags)]
+	if buildContext.InstallSuffix != "" {
+		ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix)
+	}
+	if p.omitDWARF {
+		ldflags = append(ldflags, "-w")
+	}
+
+	// If the user has not specified the -extld option, then specify the
+	// appropriate linker. In case of C++ code, use the compiler named
+	// by the CXX environment variable or defaultCXX if CXX is not set.
+	// Else, use the CC environment variable and defaultCC as fallback.
+	extld := false
+	for _, f := range ldflags {
+		if f == "-extld" || strings.HasPrefix(f, "-extld=") {
+			extld = true
+			break
+		}
+	}
+	if !extld {
+		var compiler []string
+		if cxx {
+			compiler = envList("CXX", defaultCXX)
+		} else {
+			compiler = envList("CC", defaultCC)
+		}
+		ldflags = append(ldflags, "-extld="+compiler[0])
+		if len(compiler) > 1 {
+			extldflags := false
+			add := strings.Join(compiler[1:], " ")
+			for i, f := range ldflags {
+				if f == "-extldflags" && i+1 < len(ldflags) {
+					ldflags[i+1] = add + " " + ldflags[i+1]
+					extldflags = true
+					break
+				} else if strings.HasPrefix(f, "-extldflags=") {
+					ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
+					extldflags = true
+					break
+				}
+			}
+			if !extldflags {
+				ldflags = append(ldflags, "-extldflags="+add)
+			}
+		}
+	}
+	return b.run(".", p.ImportPath, nil, tool(archChar+"l"), "-o", out, importArgs, ldflags, mainpkg)
+}
+
+func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
+	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
+	cfile = mkAbs(p.Dir, cfile)
+	args := stringList(tool(archChar+"c"), "-F", "-V", "-w", "-trimpath", b.work, "-I", objdir, "-I", inc, "-o", ofile, buildCcflags, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, cfile)
+	return b.run(p.Dir, p.ImportPath, nil, args)
+}
+
+// The Gccgo toolchain.
+type gccgoToolchain struct{}
+
+var gccgoName, gccgoBin string
+
+func init() {
+	gccgoName = os.Getenv("GCCGO")
+	if gccgoName == "" {
+		gccgoName = defaultGCCGO
+	}
+	gccgoBin, _ = exec.LookPath(gccgoName)
+}
+
+func (gccgoToolchain) compiler() string {
+	return gccgoBin
+}
+
+func (gccgoToolchain) linker() string {
+	return gccgoBin
+}
+
+func (tools gccgoToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
+	out := p.Name + ".o"
+	ofile = obj + out
+	gcargs := []string{"-g"}
+	gcargs = append(gcargs, b.gccArchArgs()...)
+	if pkgpath := gccgoPkgpath(p); pkgpath != "" {
+		gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath)
+	}
+	if p.localPrefix != "" {
+		gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix)
+	}
+	args := stringList(tools.compiler(), importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
+	for _, f := range gofiles {
+		args = append(args, mkAbs(p.Dir, f))
+	}
+
+	output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
+	return ofile, output, err
+}
+
+func (tools gccgoToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
+	sfile = mkAbs(p.Dir, sfile)
+	defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
+	if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
+		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
+	}
+	defs = append(defs, b.gccArchArgs()...)
+	return b.run(p.Dir, p.ImportPath, nil, tools.compiler(), "-c", "-I", obj, "-o", ofile, defs, sfile)
+}
+
+func (gccgoToolchain) pkgpath(basedir string, p *Package) string {
+	end := filepath.FromSlash(p.ImportPath + ".a")
+	afile := filepath.Join(basedir, end)
+	// add "lib" to the final element
+	return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile))
+}
+
+func (gccgoToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
+	var absOfiles []string
+	for _, f := range ofiles {
+		absOfiles = append(absOfiles, mkAbs(objDir, f))
+	}
+	return b.run(p.Dir, p.ImportPath, nil, "ar", "cru", mkAbs(objDir, afile), absOfiles)
+}
+
+func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
+	// gccgo needs explicit linking with all package dependencies,
+	// and all LDFLAGS from cgo dependencies.
+	apackagesSeen := make(map[*Package]bool)
+	afiles := []string{}
+	ldflags := b.gccArchArgs()
+	cgoldflags := []string{}
+	usesCgo := false
+	cxx := false
+	objc := false
+
+	// Prefer the output of an install action to the output of a build action,
+	// because the install action will delete the output of the build action.
+	// Iterate over the list backward (reverse dependency order) so that we
+	// always see the install before the build.
+	for i := len(allactions) - 1; i >= 0; i-- {
+		a := allactions[i]
+		if !a.p.Standard {
+			if a.p != nil && !apackagesSeen[a.p] {
+				apackagesSeen[a.p] = true
+				if a.p.fake {
+					// move _test files to the top of the link order
+					afiles = append([]string{a.target}, afiles...)
+				} else {
+					afiles = append(afiles, a.target)
+				}
+			}
+		}
+	}
+
+	for _, a := range allactions {
+		if a.p != nil {
+			cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
+			if len(a.p.CgoFiles) > 0 {
+				usesCgo = true
+			}
+			if a.p.usesSwig() {
+				usesCgo = true
+			}
+			if len(a.p.CXXFiles) > 0 {
+				cxx = true
+			}
+			if len(a.p.MFiles) > 0 {
+				objc = true
+			}
+		}
+	}
+	ldflags = append(ldflags, afiles...)
+	ldflags = append(ldflags, cgoldflags...)
+	ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)
+	ldflags = append(ldflags, p.CgoLDFLAGS...)
+	if usesCgo && goos == "linux" {
+		ldflags = append(ldflags, "-Wl,-E")
+	}
+	if cxx {
+		ldflags = append(ldflags, "-lstdc++")
+	}
+	if objc {
+		ldflags = append(ldflags, "-lobjc")
+	}
+	return b.run(".", p.ImportPath, nil, tools.linker(), "-o", out, ofiles, "-Wl,-(", ldflags, "-Wl,-)", buildGccgoflags)
+}
+
+func (gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
+	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
+	cfile = mkAbs(p.Dir, cfile)
+	defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
+	defs = append(defs, b.gccArchArgs()...)
+	if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
+		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
+	}
+	// TODO: Support using clang here (during gccgo build)?
+	return b.run(p.Dir, p.ImportPath, nil, "gcc", "-Wall", "-g",
+		"-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
+}
+
+func gccgoPkgpath(p *Package) string {
+	if p.build.IsCommand() && !p.forceLibrary {
+		return ""
+	}
+	return p.ImportPath
+}
+
+func gccgoCleanPkgpath(p *Package) string {
+	clean := func(r rune) rune {
+		switch {
+		case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
+			'0' <= r && r <= '9':
+			return r
+		}
+		return '_'
+	}
+	return strings.Map(clean, gccgoPkgpath(p))
+}
+
+// libgcc returns the filename for libgcc, as determined by invoking gcc with
+// the -print-libgcc-file-name option.
+func (b *builder) libgcc(p *Package) (string, error) {
+	var buf bytes.Buffer
+
+	gccCmd := b.gccCmd(p.Dir)
+
+	prev := b.print
+	if buildN {
+		// In -n mode we temporarily swap out the builder's
+		// print function to capture the command-line. This
+		// let's us assign it to $LIBGCC and produce a valid
+		// buildscript for cgo packages.
+		b.print = func(a ...interface{}) (int, error) {
+			return fmt.Fprint(&buf, a...)
+		}
+	}
+	f, err := b.runOut(p.Dir, p.ImportPath, nil, gccCmd, "-print-libgcc-file-name")
+	if err != nil {
+		return "", fmt.Errorf("gcc -print-libgcc-file-name: %v (%s)", err, f)
+	}
+	if buildN {
+		s := fmt.Sprintf("LIBGCC=$(%s)\n", buf.Next(buf.Len()-1))
+		b.print = prev
+		b.print(s)
+		return "$LIBGCC", nil
+	}
+
+	// clang might not be able to find libgcc, and in that case,
+	// it will simply return "libgcc.a", which is of no use to us.
+	if strings.Contains(gccCmd[0], "clang") && !filepath.IsAbs(string(f)) {
+		return "", nil
+	}
+
+	return strings.Trim(string(f), "\r\n"), nil
+}
+
+// gcc runs the gcc C compiler to create an object from a single C file.
+func (b *builder) gcc(p *Package, out string, flags []string, cfile string) error {
+	return b.ccompile(p, out, flags, cfile, b.gccCmd(p.Dir))
+}
+
+// gxx runs the g++ C++ compiler to create an object from a single C++ file.
+func (b *builder) gxx(p *Package, out string, flags []string, cxxfile string) error {
+	return b.ccompile(p, out, flags, cxxfile, b.gxxCmd(p.Dir))
+}
+
+// ccompile runs the given C or C++ compiler and creates an object from a single source file.
+func (b *builder) ccompile(p *Package, out string, flags []string, file string, compiler []string) error {
+	file = mkAbs(p.Dir, file)
+	return b.run(p.Dir, p.ImportPath, nil, compiler, flags, "-o", out, "-c", file)
+}
+
+// gccld runs the gcc linker to create an executable from a set of object files.
+func (b *builder) gccld(p *Package, out string, flags []string, obj []string) error {
+	var cmd []string
+	if len(p.CXXFiles) > 0 {
+		cmd = b.gxxCmd(p.Dir)
+	} else {
+		cmd = b.gccCmd(p.Dir)
+	}
+	return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, obj, flags)
+}
+
+// gccCmd returns a gcc command line prefix
+// defaultCC is defined in zdefaultcc.go, written by cmd/dist.
+func (b *builder) gccCmd(objdir string) []string {
+	return b.ccompilerCmd("CC", defaultCC, objdir)
+}
+
+// gxxCmd returns a g++ command line prefix
+// defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
+func (b *builder) gxxCmd(objdir string) []string {
+	return b.ccompilerCmd("CXX", defaultCXX, objdir)
+}
+
+// ccompilerCmd returns a command line prefix for the given environment
+// variable and using the default command when the variable is empty.
+func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
+	// NOTE: env.go's mkEnv knows that the first three
+	// strings returned are "gcc", "-I", objdir (and cuts them off).
+
+	compiler := envList(envvar, defcmd)
+	a := []string{compiler[0], "-I", objdir}
+	a = append(a, compiler[1:]...)
+
+	// Definitely want -fPIC but on Windows gcc complains
+	// "-fPIC ignored for target (all code is position independent)"
+	if goos != "windows" {
+		a = append(a, "-fPIC")
+	}
+	a = append(a, b.gccArchArgs()...)
+	// gcc-4.5 and beyond require explicit "-pthread" flag
+	// for multithreading with pthread library.
+	if buildContext.CgoEnabled {
+		switch goos {
+		case "windows":
+			a = append(a, "-mthreads")
+		default:
+			a = append(a, "-pthread")
+		}
+	}
+
+	if strings.Contains(a[0], "clang") {
+		// disable ASCII art in clang errors, if possible
+		a = append(a, "-fno-caret-diagnostics")
+		// clang is too smart about command-line arguments
+		a = append(a, "-Qunused-arguments")
+	}
+
+	// disable word wrapping in error messages
+	a = append(a, "-fmessage-length=0")
+
+	// On OS X, some of the compilers behave as if -fno-common
+	// is always set, and the Mach-O linker in 6l/8l assumes this.
+	// See http://golang.org/issue/3253.
+	if goos == "darwin" {
+		a = append(a, "-fno-common")
+	}
+
+	return a
+}
+
+// gccArchArgs returns arguments to pass to gcc based on the architecture.
+func (b *builder) gccArchArgs() []string {
+	switch archChar {
+	case "8":
+		return []string{"-m32"}
+	case "6":
+		return []string{"-m64"}
+	case "5":
+		return []string{"-marm"} // not thumb
+	}
+	return nil
+}
+
+// envList returns the value of the given environment variable broken
+// into fields, using the default value when the variable is empty.
+func envList(key, def string) []string {
+	v := os.Getenv(key)
+	if v == "" {
+		v = def
+	}
+	return strings.Fields(v)
+}
+
+// Return the flags to use when invoking the C or C++ compilers, or cgo.
+func (b *builder) cflags(p *Package, def bool) (cppflags, cflags, cxxflags, ldflags []string) {
+	var defaults string
+	if def {
+		defaults = "-g -O2"
+	}
+
+	cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
+	cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
+	cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
+	ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
+	return
+}
+
+var cgoRe = regexp.MustCompile(`[/\\:]`)
+
+var (
+	cgoLibGccFile     string
+	cgoLibGccErr      error
+	cgoLibGccFileOnce sync.Once
+)
+
+func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
+	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoLDFLAGS := b.cflags(p, true)
+	_, cgoexeCFLAGS, _, _ := b.cflags(p, false)
+
+	// If we are compiling Objective-C code, then we need to link against libobjc
+	if len(mfiles) > 0 {
+		cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
+	}
+
+	if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
+		out, err := b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--cflags", pkgs)
+		if err != nil {
+			b.showOutput(p.Dir, "pkg-config --cflags "+strings.Join(pkgs, " "), string(out))
+			b.print(err.Error() + "\n")
+			return nil, nil, errPrintedOutput
+		}
+		if len(out) > 0 {
+			cgoCPPFLAGS = append(cgoCPPFLAGS, strings.Fields(string(out))...)
+		}
+		out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--libs", pkgs)
+		if err != nil {
+			b.showOutput(p.Dir, "pkg-config --libs "+strings.Join(pkgs, " "), string(out))
+			b.print(err.Error() + "\n")
+			return nil, nil, errPrintedOutput
+		}
+		if len(out) > 0 {
+			cgoLDFLAGS = append(cgoLDFLAGS, strings.Fields(string(out))...)
+		}
+	}
+
+	// Allows including _cgo_export.h from .[ch] files in the package.
+	cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)
+
+	// cgo
+	// TODO: CGOPKGPATH, CGO_FLAGS?
+	gofiles := []string{obj + "_cgo_gotypes.go"}
+	cfiles := []string{"_cgo_main.c", "_cgo_export.c"}
+	for _, fn := range p.CgoFiles {
+		f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
+		gofiles = append(gofiles, obj+f+"cgo1.go")
+		cfiles = append(cfiles, f+"cgo2.c")
+	}
+	defunC := obj + "_cgo_defun.c"
+
+	cgoflags := []string{}
+	// TODO: make cgo not depend on $GOARCH?
+
+	objExt := archChar
+
+	if p.Standard && p.ImportPath == "runtime/cgo" {
+		cgoflags = append(cgoflags, "-import_runtime_cgo=false")
+	}
+	if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/cgo") {
+		cgoflags = append(cgoflags, "-import_syscall=false")
+	}
+
+	// Update $CGO_LDFLAGS with p.CgoLDFLAGS.
+	var cgoenv []string
+	if len(cgoLDFLAGS) > 0 {
+		flags := make([]string, len(cgoLDFLAGS))
+		for i, f := range cgoLDFLAGS {
+			flags[i] = strconv.Quote(f)
+		}
+		cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
+	}
+
+	if _, ok := buildToolchain.(gccgoToolchain); ok {
+		cgoflags = append(cgoflags, "-gccgo")
+		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
+			cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
+		}
+		objExt = "o"
+	}
+	if err := b.run(p.Dir, p.ImportPath, cgoenv, cgoExe, "-objdir", obj, cgoflags, "--", cgoCPPFLAGS, cgoexeCFLAGS, p.CgoFiles); err != nil {
+		return nil, nil, err
+	}
+	outGo = append(outGo, gofiles...)
+
+	// cc _cgo_defun.c
+	defunObj := obj + "_cgo_defun." + objExt
+	if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
+		return nil, nil, err
+	}
+	outObj = append(outObj, defunObj)
+
+	// gcc
+	var linkobj []string
+
+	var bareLDFLAGS []string
+	// filter out -lsomelib, -l somelib, *.{so,dll,dylib}, and (on Darwin) -framework X
+	for i := 0; i < len(cgoLDFLAGS); i++ {
+		f := cgoLDFLAGS[i]
+		switch {
+		// skip "-lc" or "-l somelib"
+		case strings.HasPrefix(f, "-l"):
+			if f == "-l" {
+				i++
+			}
+		// skip "-framework X" on Darwin
+		case goos == "darwin" && f == "-framework":
+			i++
+		// skip "*.{dylib,so,dll}"
+		case strings.HasSuffix(f, ".dylib"),
+			strings.HasSuffix(f, ".so"),
+			strings.HasSuffix(f, ".dll"):
+			continue
+		default:
+			bareLDFLAGS = append(bareLDFLAGS, f)
+		}
+	}
+
+	cgoLibGccFileOnce.Do(func() {
+		cgoLibGccFile, cgoLibGccErr = b.libgcc(p)
+	})
+	if cgoLibGccFile == "" && cgoLibGccErr != nil {
+		return nil, nil, err
+	}
+
+	var staticLibs []string
+	if goos == "windows" {
+		// libmingw32 and libmingwex might also use libgcc, so libgcc must come last,
+		// and they also have some inter-dependencies, so must use linker groups.
+		staticLibs = []string{"-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group"}
+	}
+	if cgoLibGccFile != "" {
+		staticLibs = append(staticLibs, cgoLibGccFile)
+	}
+
+	cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
+	for _, cfile := range cfiles {
+		ofile := obj + cfile[:len(cfile)-1] + "o"
+		if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil {
+			return nil, nil, err
+		}
+		linkobj = append(linkobj, ofile)
+		if !strings.HasSuffix(ofile, "_cgo_main.o") {
+			outObj = append(outObj, ofile)
+		}
+	}
+
+	for _, file := range gccfiles {
+		ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
+		if err := b.gcc(p, ofile, cflags, file); err != nil {
+			return nil, nil, err
+		}
+		linkobj = append(linkobj, ofile)
+		outObj = append(outObj, ofile)
+	}
+
+	cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
+	for _, file := range gxxfiles {
+		// Append .o to the file, just in case the pkg has file.c and file.cpp
+		ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
+		if err := b.gxx(p, ofile, cxxflags, file); err != nil {
+			return nil, nil, err
+		}
+		linkobj = append(linkobj, ofile)
+		outObj = append(outObj, ofile)
+	}
+
+	for _, file := range mfiles {
+		// Append .o to the file, just in case the pkg has file.c and file.m
+		ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
+		if err := b.gcc(p, ofile, cflags, file); err != nil {
+			return nil, nil, err
+		}
+		linkobj = append(linkobj, ofile)
+		outObj = append(outObj, ofile)
+	}
+
+	linkobj = append(linkobj, p.SysoFiles...)
+	dynobj := obj + "_cgo_.o"
+	if goarch == "arm" && goos == "linux" { // we need to use -pie for Linux/ARM to get accurate imported sym
+		cgoLDFLAGS = append(cgoLDFLAGS, "-pie")
+	}
+	if err := b.gccld(p, dynobj, cgoLDFLAGS, linkobj); err != nil {
+		return nil, nil, err
+	}
+	if goarch == "arm" && goos == "linux" { // but we don't need -pie for normal cgo programs
+		cgoLDFLAGS = cgoLDFLAGS[0 : len(cgoLDFLAGS)-1]
+	}
+
+	if _, ok := buildToolchain.(gccgoToolchain); ok {
+		// we don't use dynimport when using gccgo.
+		return outGo, outObj, nil
+	}
+
+	// cgo -dynimport
+	importC := obj + "_cgo_import.c"
+	cgoflags = []string{}
+	if p.Standard && p.ImportPath == "runtime/cgo" {
+		cgoflags = append(cgoflags, "-dynlinker") // record path to dynamic linker
+	}
+	if err := b.run(p.Dir, p.ImportPath, nil, cgoExe, "-objdir", obj, "-dynimport", dynobj, "-dynout", importC, cgoflags); err != nil {
+		return nil, nil, err
+	}
+
+	// cc _cgo_import.ARCH
+	importObj := obj + "_cgo_import." + objExt
+	if err := buildToolchain.cc(b, p, obj, importObj, importC); err != nil {
+		return nil, nil, err
+	}
+
+	ofile := obj + "_all.o"
+	var gccObjs, nonGccObjs []string
+	for _, f := range outObj {
+		if strings.HasSuffix(f, ".o") {
+			gccObjs = append(gccObjs, f)
+		} else {
+			nonGccObjs = append(nonGccObjs, f)
+		}
+	}
+	if err := b.gccld(p, ofile, stringList(bareLDFLAGS, "-Wl,-r", "-nostdlib", staticLibs), gccObjs); err != nil {
+		return nil, nil, err
+	}
+
+	// NOTE(rsc): The importObj is a 5c/6c/8c object and on Windows
+	// must be processed before the gcc-generated objects.
+	// Put it first.  http://golang.org/issue/2601
+	outObj = stringList(importObj, nonGccObjs, ofile)
+
+	return outGo, outObj, nil
+}
+
+// Run SWIG on all SWIG input files.
+// TODO: Don't build a shared library, once SWIG emits the necessary
+// pragmas for external linking.
+func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
+	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
+	cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
+	cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
+
+	for _, file := range gccfiles {
+		ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
+		if err := b.gcc(p, ofile, cflags, file); err != nil {
+			return nil, nil, err
+		}
+		outObj = append(outObj, ofile)
+	}
+
+	for _, file := range gxxfiles {
+		// Append .o to the file, just in case the pkg has file.c and file.cpp
+		ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
+		if err := b.gxx(p, ofile, cxxflags, file); err != nil {
+			return nil, nil, err
+		}
+		outObj = append(outObj, ofile)
+	}
+
+	for _, file := range mfiles {
+		// Append .o to the file, just in case the pkg has file.c and file.cpp
+		ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
+		if err := b.gcc(p, ofile, cflags, file); err != nil {
+			return nil, nil, err
+		}
+		outObj = append(outObj, ofile)
+	}
+
+	if err := b.swigVersionCheck(); err != nil {
+		return nil, nil, err
+	}
+
+	intgosize, err := b.swigIntSize(obj)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	for _, f := range p.SwigFiles {
+		goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, false, intgosize)
+		if err != nil {
+			return nil, nil, err
+		}
+		if goFile != "" {
+			outGo = append(outGo, goFile)
+		}
+		if objFile != "" {
+			outObj = append(outObj, objFile)
+		}
+		if gccObjFile != "" {
+			outObj = append(outObj, gccObjFile)
+		}
+	}
+	for _, f := range p.SwigCXXFiles {
+		goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, true, intgosize)
+		if err != nil {
+			return nil, nil, err
+		}
+		if goFile != "" {
+			outGo = append(outGo, goFile)
+		}
+		if objFile != "" {
+			outObj = append(outObj, objFile)
+		}
+		if gccObjFile != "" {
+			outObj = append(outObj, gccObjFile)
+		}
+	}
+	return outGo, outObj, nil
+}
+
+// Make sure SWIG is new enough.
+var (
+	swigCheckOnce sync.Once
+	swigCheck     error
+)
+
+func (b *builder) swigDoVersionCheck() error {
+	out, err := b.runOut("", "", nil, "swig", "-version")
+	if err != nil {
+		return err
+	}
+	re := regexp.MustCompile(`[vV]ersion +([\d])`)
+	matches := re.FindSubmatch(out)
+	if matches == nil {
+		// Can't find version number; hope for the best.
+		return nil
+	}
+	major, err := strconv.Atoi(string(matches[1]))
+	if err != nil {
+		// Can't find version number; hope for the best.
+		return nil
+	}
+	if major < 3 {
+		return errors.New("must have SWIG version >= 3.0")
+	}
+	return nil
+}
+
+func (b *builder) swigVersionCheck() error {
+	swigCheckOnce.Do(func() {
+		swigCheck = b.swigDoVersionCheck()
+	})
+	return swigCheck
+}
+
+// This code fails to build if sizeof(int) <= 32
+const swigIntSizeCode = `
+package main
+const i int = 1 << 32
+`
+
+// Determine the size of int on the target system for the -intgosize option
+// of swig >= 2.0.9
+func (b *builder) swigIntSize(obj string) (intsize string, err error) {
+	if buildN {
+		return "$INTBITS", nil
+	}
+	src := filepath.Join(b.work, "swig_intsize.go")
+	if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0644); err != nil {
+		return
+	}
+	srcs := []string{src}
+
+	p := goFilesPackage(srcs)
+
+	if _, _, e := buildToolchain.gc(b, p, "", obj, nil, srcs); e != nil {
+		return "32", nil
+	}
+	return "64", nil
+}
+
+// Run SWIG on one SWIG input file.
+func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize string) (outGo, outObj, objGccObj string, err error) {
+	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
+	var cflags []string
+	if cxx {
+		cflags = stringList(cgoCPPFLAGS, cgoCXXFLAGS)
+	} else {
+		cflags = stringList(cgoCPPFLAGS, cgoCFLAGS)
+	}
+
+	n := 5 // length of ".swig"
+	if cxx {
+		n = 8 // length of ".swigcxx"
+	}
+	base := file[:len(file)-n]
+	goFile := base + ".go"
+	cBase := base + "_gc."
+	gccBase := base + "_wrap."
+	gccExt := "c"
+	if cxx {
+		gccExt = "cxx"
+	}
+
+	_, gccgo := buildToolchain.(gccgoToolchain)
+
+	// swig
+	args := []string{
+		"-go",
+		"-intgosize", intgosize,
+		"-module", base,
+		"-o", obj + gccBase + gccExt,
+		"-outdir", obj,
+	}
+	if gccgo {
+		args = append(args, "-gccgo")
+		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
+			args = append(args, "-go-pkgpath", pkgpath)
+		}
+	}
+	if cxx {
+		args = append(args, "-c++")
+	}
+
+	if out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file); err != nil {
+		if len(out) > 0 {
+			if bytes.Contains(out, []byte("Unrecognized option -intgosize")) {
+				return "", "", "", errors.New("must have SWIG version >= 3.0")
+			}
+			b.showOutput(p.Dir, p.ImportPath, b.processOutput(out))
+			return "", "", "", errPrintedOutput
+		}
+		return "", "", "", err
+	}
+
+	var cObj string
+	if !gccgo {
+		// cc
+		cObj = obj + cBase + archChar
+		if err := buildToolchain.cc(b, p, obj, cObj, obj+cBase+"c"); err != nil {
+			return "", "", "", err
+		}
+	}
+
+	// gcc
+	gccObj := obj + gccBase + "o"
+	if !cxx {
+		if err := b.gcc(p, gccObj, cflags, obj+gccBase+gccExt); err != nil {
+			return "", "", "", err
+		}
+	} else {
+		if err := b.gxx(p, gccObj, cflags, obj+gccBase+gccExt); err != nil {
+			return "", "", "", err
+		}
+	}
+
+	return obj + goFile, cObj, gccObj, nil
+}
+
+// An actionQueue is a priority queue of actions.
+type actionQueue []*action
+
+// Implement heap.Interface
+func (q *actionQueue) Len() int           { return len(*q) }
+func (q *actionQueue) Swap(i, j int)      { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
+func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority }
+func (q *actionQueue) Push(x interface{}) { *q = append(*q, x.(*action)) }
+func (q *actionQueue) Pop() interface{} {
+	n := len(*q) - 1
+	x := (*q)[n]
+	*q = (*q)[:n]
+	return x
+}
+
+func (q *actionQueue) push(a *action) {
+	heap.Push(q, a)
+}
+
+func (q *actionQueue) pop() *action {
+	return heap.Pop(q).(*action)
+}
+
+func raceInit() {
+	if !buildRace {
+		return
+	}
+	if goarch != "amd64" || goos != "linux" && goos != "darwin" && goos != "windows" {
+		fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0])
+		os.Exit(2)
+	}
+	buildGcflags = append(buildGcflags, "-race")
+	buildLdflags = append(buildLdflags, "-race")
+	buildCcflags = append(buildCcflags, "-D", "RACE")
+	if buildContext.InstallSuffix != "" {
+		buildContext.InstallSuffix += "_"
+	}
+	buildContext.InstallSuffix += "race"
+	buildContext.BuildTags = append(buildContext.BuildTags, "race")
+}
+
+// defaultSuffix returns file extension used for command files in
+// current os environment.
+func defaultSuffix() string {
+	switch runtime.GOOS {
+	case "windows":
+		return ".bat"
+	case "plan9":
+		return ".rc"
+	default:
+		return ".bash"
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/clean.go b/third_party/gofrontend/libgo/go/cmd/go/clean.go
new file mode 100644
index 0000000..16054a5
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/clean.go
@@ -0,0 +1,248 @@
+// 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 main
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+var cmdClean = &Command{
+	UsageLine: "clean [-i] [-r] [-n] [-x] [build flags] [packages]",
+	Short:     "remove object files",
+	Long: `
+Clean removes object files from package source directories.
+The go command builds most objects in a temporary directory,
+so go clean is mainly concerned with object files left by other
+tools or by manual invocations of go build.
+
+Specifically, clean removes the following files from each of the
+source directories corresponding to the import paths:
+
+	_obj/            old object directory, left from Makefiles
+	_test/           old test directory, left from Makefiles
+	_testmain.go     old gotest file, left from Makefiles
+	test.out         old test log, left from Makefiles
+	build.out        old test log, left from Makefiles
+	*.[568ao]        object files, left from Makefiles
+
+	DIR(.exe)        from go build
+	DIR.test(.exe)   from go test -c
+	MAINFILE(.exe)   from go build MAINFILE.go
+	*.so             from SWIG
+
+In the list, DIR represents the final path element of the
+directory, and MAINFILE is the base name of any Go source
+file in the directory that is not included when building
+the package.
+
+The -i flag causes clean to remove the corresponding installed
+archive or binary (what 'go install' would create).
+
+The -n flag causes clean to print the remove commands it would execute,
+but not run them.
+
+The -r flag causes clean to be applied recursively to all the
+dependencies of the packages named by the import paths.
+
+The -x flag causes clean to print remove commands as it executes them.
+
+For more about build flags, see 'go help build'.
+
+For more about specifying packages, see 'go help packages'.
+	`,
+}
+
+var cleanI bool // clean -i flag
+var cleanR bool // clean -r flag
+
+func init() {
+	// break init cycle
+	cmdClean.Run = runClean
+
+	cmdClean.Flag.BoolVar(&cleanI, "i", false, "")
+	cmdClean.Flag.BoolVar(&cleanR, "r", false, "")
+	// -n and -x are important enough to be
+	// mentioned explicitly in the docs but they
+	// are part of the build flags.
+
+	addBuildFlags(cmdClean)
+}
+
+func runClean(cmd *Command, args []string) {
+	for _, pkg := range packagesAndErrors(args) {
+		clean(pkg)
+	}
+}
+
+var cleaned = map[*Package]bool{}
+
+// TODO: These are dregs left by Makefile-based builds.
+// Eventually, can stop deleting these.
+var cleanDir = map[string]bool{
+	"_test": true,
+	"_obj":  true,
+}
+
+var cleanFile = map[string]bool{
+	"_testmain.go": true,
+	"test.out":     true,
+	"build.out":    true,
+	"a.out":        true,
+}
+
+var cleanExt = map[string]bool{
+	".5":  true,
+	".6":  true,
+	".8":  true,
+	".a":  true,
+	".o":  true,
+	".so": true,
+}
+
+func clean(p *Package) {
+	if cleaned[p] {
+		return
+	}
+	cleaned[p] = true
+
+	if p.Dir == "" {
+		errorf("can't load package: %v", p.Error)
+		return
+	}
+	dirs, err := ioutil.ReadDir(p.Dir)
+	if err != nil {
+		errorf("go clean %s: %v", p.Dir, err)
+		return
+	}
+
+	var b builder
+	b.print = fmt.Print
+
+	packageFile := map[string]bool{}
+	if p.Name != "main" {
+		// Record which files are not in package main.
+		// The others are.
+		keep := func(list []string) {
+			for _, f := range list {
+				packageFile[f] = true
+			}
+		}
+		keep(p.GoFiles)
+		keep(p.CgoFiles)
+		keep(p.TestGoFiles)
+		keep(p.XTestGoFiles)
+	}
+
+	_, elem := filepath.Split(p.Dir)
+	var allRemove []string
+
+	// Remove dir-named executable only if this is package main.
+	if p.Name == "main" {
+		allRemove = append(allRemove,
+			elem,
+			elem+".exe",
+		)
+	}
+
+	// Remove package test executables.
+	allRemove = append(allRemove,
+		elem+".test",
+		elem+".test.exe",
+	)
+
+	// Remove a potential executable for each .go file in the directory that
+	// is not part of the directory's package.
+	for _, dir := range dirs {
+		name := dir.Name()
+		if packageFile[name] {
+			continue
+		}
+		if !dir.IsDir() && strings.HasSuffix(name, ".go") {
+			// TODO(adg,rsc): check that this .go file is actually
+			// in "package main", and therefore capable of building
+			// to an executable file.
+			base := name[:len(name)-len(".go")]
+			allRemove = append(allRemove, base, base+".exe")
+		}
+	}
+
+	if buildN || buildX {
+		b.showcmd(p.Dir, "rm -f %s", strings.Join(allRemove, " "))
+	}
+
+	toRemove := map[string]bool{}
+	for _, name := range allRemove {
+		toRemove[name] = true
+	}
+	for _, dir := range dirs {
+		name := dir.Name()
+		if dir.IsDir() {
+			// TODO: Remove once Makefiles are forgotten.
+			if cleanDir[name] {
+				if buildN || buildX {
+					b.showcmd(p.Dir, "rm -r %s", name)
+					if buildN {
+						continue
+					}
+				}
+				if err := os.RemoveAll(filepath.Join(p.Dir, name)); err != nil {
+					errorf("go clean: %v", err)
+				}
+			}
+			continue
+		}
+
+		if buildN {
+			continue
+		}
+
+		if cleanFile[name] || cleanExt[filepath.Ext(name)] || toRemove[name] {
+			removeFile(filepath.Join(p.Dir, name))
+		}
+	}
+
+	if cleanI && p.target != "" {
+		if buildN || buildX {
+			b.showcmd("", "rm -f %s", p.target)
+		}
+		if !buildN {
+			removeFile(p.target)
+		}
+	}
+
+	if cleanR {
+		for _, p1 := range p.imports {
+			clean(p1)
+		}
+	}
+}
+
+// removeFile tries to remove file f, if error other than file doesn't exist
+// occurs, it will report the error.
+func removeFile(f string) {
+	err := os.Remove(f)
+	if err == nil || os.IsNotExist(err) {
+		return
+	}
+	// Windows does not allow deletion of a binary file while it is executing.
+	if toolIsWindows {
+		// Remove lingering ~ file from last attempt.
+		if _, err2 := os.Stat(f + "~"); err2 == nil {
+			os.Remove(f + "~")
+		}
+		// Try to move it out of the way. If the move fails,
+		// which is likely, we'll try again the
+		// next time we do an install of this binary.
+		if err2 := os.Rename(f, f+"~"); err2 == nil {
+			os.Remove(f + "~")
+			return
+		}
+	}
+	errorf("go clean: %v", err)
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/context.go b/third_party/gofrontend/libgo/go/cmd/go/context.go
new file mode 100644
index 0000000..68e5182
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/context.go
@@ -0,0 +1,36 @@
+// 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 (
+	"go/build"
+)
+
+type Context struct {
+	GOARCH        string   `json:",omitempty"` // target architecture
+	GOOS          string   `json:",omitempty"` // target operating system
+	GOROOT        string   `json:",omitempty"` // Go root
+	GOPATH        string   `json:",omitempty"` // Go path
+	CgoEnabled    bool     `json:",omitempty"` // whether cgo can be used
+	UseAllFiles   bool     `json:",omitempty"` // use files regardless of +build lines, file names
+	Compiler      string   `json:",omitempty"` // compiler to assume when computing target paths
+	BuildTags     []string `json:",omitempty"` // build constraints to match in +build lines
+	ReleaseTags   []string `json:",omitempty"` // releases the current release is compatible with
+	InstallSuffix string   `json:",omitempty"` // suffix to use in the name of the install dir
+}
+
+func newContext(c *build.Context) *Context {
+	return &Context{
+		GOARCH:        c.GOARCH,
+		GOOS:          c.GOOS,
+		GOROOT:        c.GOROOT,
+		CgoEnabled:    c.CgoEnabled,
+		UseAllFiles:   c.UseAllFiles,
+		Compiler:      c.Compiler,
+		BuildTags:     c.BuildTags,
+		ReleaseTags:   c.ReleaseTags,
+		InstallSuffix: c.InstallSuffix,
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/discovery.go b/third_party/gofrontend/libgo/go/cmd/go/discovery.go
new file mode 100644
index 0000000..b9f4279
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/discovery.go
@@ -0,0 +1,83 @@
+// 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.
+
+// +build !cmd_go_bootstrap
+
+// This code is compiled into the real 'go' binary, but it is not
+// compiled into the binary that is built during all.bash, so as
+// to avoid needing to build net (and thus use cgo) during the
+// bootstrap process.
+
+package main
+
+import (
+	"encoding/xml"
+	"fmt"
+	"io"
+	"strings"
+)
+
+// charsetReader returns a reader for the given charset. Currently
+// it only supports UTF-8 and ASCII. Otherwise, it returns a meaningful
+// error which is printed by go get, so the user can find why the package
+// wasn't downloaded if the encoding is not supported. Note that, in
+// order to reduce potential errors, ASCII is treated as UTF-8 (i.e. characters
+// greater than 0x7f are not rejected).
+func charsetReader(charset string, input io.Reader) (io.Reader, error) {
+	switch strings.ToLower(charset) {
+	case "ascii":
+		return input, nil
+	default:
+		return nil, fmt.Errorf("can't decode XML document using charset %q", charset)
+	}
+}
+
+// parseMetaGoImports returns meta imports from the HTML in r.
+// Parsing ends at the end of the <head> section or the beginning of the <body>.
+func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
+	d := xml.NewDecoder(r)
+	d.CharsetReader = charsetReader
+	d.Strict = false
+	var t xml.Token
+	for {
+		t, err = d.Token()
+		if err != nil {
+			if err == io.EOF {
+				err = nil
+			}
+			return
+		}
+		if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") {
+			return
+		}
+		if e, ok := t.(xml.EndElement); ok && strings.EqualFold(e.Name.Local, "head") {
+			return
+		}
+		e, ok := t.(xml.StartElement)
+		if !ok || !strings.EqualFold(e.Name.Local, "meta") {
+			continue
+		}
+		if attrValue(e.Attr, "name") != "go-import" {
+			continue
+		}
+		if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 3 {
+			imports = append(imports, metaImport{
+				Prefix:   f[0],
+				VCS:      f[1],
+				RepoRoot: f[2],
+			})
+		}
+	}
+}
+
+// attrValue returns the attribute value for the case-insensitive key
+// `name', or the empty string if nothing is found.
+func attrValue(attrs []xml.Attr, name string) string {
+	for _, a := range attrs {
+		if strings.EqualFold(a.Name.Local, name) {
+			return a.Value
+		}
+	}
+	return ""
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/doc.go b/third_party/gofrontend/libgo/go/cmd/go/doc.go
new file mode 100644
index 0000000..9840804
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/doc.go
@@ -0,0 +1,990 @@
+// Copyright 2011 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.
+
+// DO NOT EDIT THIS FILE. GENERATED BY mkdoc.sh.
+// Edit the documentation in other files and rerun mkdoc.sh to generate this one.
+
+/*
+Go is a tool for managing Go source code.
+
+Usage:
+
+	go command [arguments]
+
+The commands are:
+
+    build       compile packages and dependencies
+    clean       remove object files
+    env         print Go environment information
+    fix         run go tool fix on packages
+    fmt         run gofmt on package sources
+    get         download and install packages and dependencies
+    install     compile and install packages and dependencies
+    list        list packages
+    run         compile and run Go program
+    test        test packages
+    tool        run specified go tool
+    version     print Go version
+    vet         run go tool vet on packages
+
+Use "go help [command]" for more information about a command.
+
+Additional help topics:
+
+    c           calling between Go and C
+    filetype    file types
+    gopath      GOPATH environment variable
+    importpath  import path syntax
+    packages    description of package lists
+    testflag    description of testing flags
+    testfunc    description of testing functions
+
+Use "go help [topic]" for more information about that topic.
+
+
+Compile packages and dependencies
+
+Usage:
+
+	go build [-o output] [-i] [build flags] [packages]
+
+Build compiles the packages named by the import paths,
+along with their dependencies, but it does not install the results.
+
+If the arguments are a list of .go files, build treats them as a list
+of source files specifying a single package.
+
+When the command line specifies a single main package,
+build writes the resulting executable to output.
+Otherwise build compiles the packages but discards the results,
+serving only as a check that the packages can be built.
+
+The -o flag specifies the output file name. If not specified, the
+output file name depends on the arguments and derives from the name
+of the package, such as p.a for package p, unless p is 'main'. If
+the package is main and file names are provided, the file name
+derives from the first file name mentioned, such as f1 for 'go build
+f1.go f2.go'; with no files provided ('go build'), the output file
+name is the base name of the containing directory.
+
+The -i flag installs the packages that are dependencies of the target.
+
+The build flags are shared by the build, clean, get, install, list, run,
+and test commands:
+
+	-a
+		force rebuilding of packages that are already up-to-date.
+	-n
+		print the commands but do not run them.
+	-p n
+		the number of builds that can be run in parallel.
+		The default is the number of CPUs available.
+	-race
+		enable data race detection.
+		Supported only on linux/amd64, darwin/amd64 and windows/amd64.
+	-v
+		print the names of packages as they are compiled.
+	-work
+		print the name of the temporary work directory and
+		do not delete it when exiting.
+	-x
+		print the commands.
+
+	-ccflags 'arg list'
+		arguments to pass on each 5c, 6c, or 8c compiler invocation.
+	-compiler name
+		name of compiler to use, as in runtime.Compiler (gccgo or gc).
+	-gccgoflags 'arg list'
+		arguments to pass on each gccgo compiler/linker invocation.
+	-gcflags 'arg list'
+		arguments to pass on each 5g, 6g, or 8g compiler invocation.
+	-installsuffix suffix
+		a suffix to use in the name of the package installation directory,
+		in order to keep output separate from default builds.
+		If using the -race flag, the install suffix is automatically set to race
+		or, if set explicitly, has _race appended to it.
+	-ldflags 'flag list'
+		arguments to pass on each 5l, 6l, or 8l linker invocation.
+	-tags 'tag list'
+		a list of build tags to consider satisfied during the build.
+		For more information about build tags, see the description of
+		build constraints in the documentation for the go/build package.
+
+The list flags accept a space-separated list of strings. To embed spaces
+in an element in the list, surround it with either single or double quotes.
+
+For more about specifying packages, see 'go help packages'.
+For more about where packages and binaries are installed,
+run 'go help gopath'.  For more about calling between Go and C/C++,
+run 'go help c'.
+
+See also: go install, go get, go clean.
+
+
+Remove object files
+
+Usage:
+
+	go clean [-i] [-r] [-n] [-x] [build flags] [packages]
+
+Clean removes object files from package source directories.
+The go command builds most objects in a temporary directory,
+so go clean is mainly concerned with object files left by other
+tools or by manual invocations of go build.
+
+Specifically, clean removes the following files from each of the
+source directories corresponding to the import paths:
+
+	_obj/            old object directory, left from Makefiles
+	_test/           old test directory, left from Makefiles
+	_testmain.go     old gotest file, left from Makefiles
+	test.out         old test log, left from Makefiles
+	build.out        old test log, left from Makefiles
+	*.[568ao]        object files, left from Makefiles
+
+	DIR(.exe)        from go build
+	DIR.test(.exe)   from go test -c
+	MAINFILE(.exe)   from go build MAINFILE.go
+	*.so             from SWIG
+
+In the list, DIR represents the final path element of the
+directory, and MAINFILE is the base name of any Go source
+file in the directory that is not included when building
+the package.
+
+The -i flag causes clean to remove the corresponding installed
+archive or binary (what 'go install' would create).
+
+The -n flag causes clean to print the remove commands it would execute,
+but not run them.
+
+The -r flag causes clean to be applied recursively to all the
+dependencies of the packages named by the import paths.
+
+The -x flag causes clean to print remove commands as it executes them.
+
+For more about build flags, see 'go help build'.
+
+For more about specifying packages, see 'go help packages'.
+
+
+Print Go environment information
+
+Usage:
+
+	go env [var ...]
+
+Env prints Go environment information.
+
+By default env prints information as a shell script
+(on Windows, a batch file).  If one or more variable
+names is given as arguments,  env prints the value of
+each named variable on its own line.
+
+
+Run go tool fix on packages
+
+Usage:
+
+	go fix [packages]
+
+Fix runs the Go fix command on the packages named by the import paths.
+
+For more about fix, see 'godoc fix'.
+For more about specifying packages, see 'go help packages'.
+
+To run fix with specific options, run 'go tool fix'.
+
+See also: go fmt, go vet.
+
+
+Run gofmt on package sources
+
+Usage:
+
+	go fmt [-n] [-x] [packages]
+
+Fmt runs the command 'gofmt -l -w' on the packages named
+by the import paths.  It prints the names of the files that are modified.
+
+For more about gofmt, see 'godoc gofmt'.
+For more about specifying packages, see 'go help packages'.
+
+The -n flag prints commands that would be executed.
+The -x flag prints commands as they are executed.
+
+To run gofmt with specific options, run gofmt itself.
+
+See also: go fix, go vet.
+
+
+Download and install packages and dependencies
+
+Usage:
+
+	go get [-d] [-fix] [-t] [-u] [build flags] [packages]
+
+Get downloads and installs the packages named by the import paths,
+along with their dependencies.
+
+The -d flag instructs get to stop after downloading the packages; that is,
+it instructs get not to install the packages.
+
+The -fix flag instructs get to run the fix tool on the downloaded packages
+before resolving dependencies or building the code.
+
+The -t flag instructs get to also download the packages required to build
+the tests for the specified packages.
+
+The -u flag instructs get to use the network to update the named packages
+and their dependencies.  By default, get uses the network to check out
+missing packages but does not use it to look for updates to existing packages.
+
+Get also accepts build flags to control the installation. See 'go help build'.
+
+When checking out or updating a package, get looks for a branch or tag
+that matches the locally installed version of Go. The most important
+rule is that if the local installation is running version "go1", get
+searches for a branch or tag named "go1". If no such version exists it
+retrieves the most recent version of the package.
+
+For more about specifying packages, see 'go help packages'.
+
+For more about how 'go get' finds source code to
+download, see 'go help importpath'.
+
+See also: go build, go install, go clean.
+
+
+Compile and install packages and dependencies
+
+Usage:
+
+	go install [build flags] [packages]
+
+Install compiles and installs the packages named by the import paths,
+along with their dependencies.
+
+For more about the build flags, see 'go help build'.
+For more about specifying packages, see 'go help packages'.
+
+See also: go build, go get, go clean.
+
+
+List packages
+
+Usage:
+
+	go list [-e] [-f format] [-json] [build flags] [packages]
+
+List lists the packages named by the import paths, one per line.
+
+The default output shows the package import path:
+
+    code.google.com/p/google-api-go-client/books/v1
+    code.google.com/p/goauth2/oauth
+    code.google.com/p/sqlite
+
+The -f flag specifies an alternate format for the list, using the
+syntax of package template.  The default output is equivalent to -f
+'{{.ImportPath}}'. The struct being passed to the template is:
+
+    type Package struct {
+        Dir        string // directory containing package sources
+        ImportPath string // import path of package in dir
+        Name       string // package name
+        Doc        string // package documentation string
+        Target     string // install path
+        Goroot     bool   // is this package in the Go root?
+        Standard   bool   // is this package part of the standard Go library?
+        Stale      bool   // would 'go install' do anything for this package?
+        Root       string // Go root or Go path dir containing this package
+
+        // Source files
+        GoFiles  []string       // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
+        CgoFiles []string       // .go sources files that import "C"
+        IgnoredGoFiles []string // .go sources ignored due to build constraints
+        CFiles   []string       // .c source files
+        CXXFiles []string       // .cc, .cxx and .cpp source files
+        MFiles   []string       // .m source files
+        HFiles   []string       // .h, .hh, .hpp and .hxx source files
+        SFiles   []string       // .s source files
+        SwigFiles []string      // .swig files
+        SwigCXXFiles []string   // .swigcxx files
+        SysoFiles []string      // .syso object files to add to archive
+
+        // Cgo directives
+        CgoCFLAGS    []string // cgo: flags for C compiler
+        CgoCPPFLAGS  []string // cgo: flags for C preprocessor
+        CgoCXXFLAGS  []string // cgo: flags for C++ compiler
+        CgoLDFLAGS   []string // cgo: flags for linker
+        CgoPkgConfig []string // cgo: pkg-config names
+
+        // Dependency information
+        Imports []string // import paths used by this package
+        Deps    []string // all (recursively) imported dependencies
+
+        // Error information
+        Incomplete bool            // this package or a dependency has an error
+        Error      *PackageError   // error loading package
+        DepsErrors []*PackageError // errors loading dependencies
+
+        TestGoFiles  []string // _test.go files in package
+        TestImports  []string // imports from TestGoFiles
+        XTestGoFiles []string // _test.go files outside package
+        XTestImports []string // imports from XTestGoFiles
+    }
+
+The template function "join" calls strings.Join.
+
+The template function "context" returns the build context, defined as:
+
+	type Context struct {
+		GOARCH        string   // target architecture
+		GOOS          string   // target operating system
+		GOROOT        string   // Go root
+		GOPATH        string   // Go path
+		CgoEnabled    bool     // whether cgo can be used
+		UseAllFiles   bool     // use files regardless of +build lines, file names
+		Compiler      string   // compiler to assume when computing target paths
+		BuildTags     []string // build constraints to match in +build lines
+		ReleaseTags   []string // releases the current release is compatible with
+		InstallSuffix string   // suffix to use in the name of the install dir
+	}
+
+For more information about the meaning of these fields see the documentation
+for the go/build package's Context type.
+
+The -json flag causes the package data to be printed in JSON format
+instead of using the template format.
+
+The -e flag changes the handling of erroneous packages, those that
+cannot be found or are malformed.  By default, the list command
+prints an error to standard error for each erroneous package and
+omits the packages from consideration during the usual printing.
+With the -e flag, the list command never prints errors to standard
+error and instead processes the erroneous packages with the usual
+printing.  Erroneous packages will have a non-empty ImportPath and
+a non-nil Error field; other information may or may not be missing
+(zeroed).
+
+For more about build flags, see 'go help build'.
+
+For more about specifying packages, see 'go help packages'.
+
+
+Compile and run Go program
+
+Usage:
+
+	go run [build flags] [-exec xprog] gofiles... [arguments...]
+
+Run compiles and runs the main package comprising the named Go source files.
+A Go source file is defined to be a file ending in a literal ".go" suffix.
+
+By default, 'go run' runs the compiled binary directly: 'a.out arguments...'.
+If the -exec flag is given, 'go run' invokes the binary using xprog: 'xprog a.out arguments...'.
+If the -exec flag is not given, GOOS or GOARCH is different from the system
+default, and a program named go_$GOOS_$GOARCH_exec can be found
+on the current search path, 'go run' invokes the binary using that program,
+for example 'go_nacl_386_exec a.out arguments...'. This allows execution of
+cross-compiled programs when a simulator or other execution method is
+available.
+
+For more about build flags, see 'go help build'.
+
+See also: go build.
+
+
+Test packages
+
+Usage:
+
+	go test [-c] [-i] [build and test flags] [packages] [flags for test binary]
+
+'Go test' automates testing the packages named by the import paths.
+It prints a summary of the test results in the format:
+
+	ok   archive/tar   0.011s
+	FAIL archive/zip   0.022s
+	ok   compress/gzip 0.033s
+	...
+
+followed by detailed output for each failed package.
+
+'Go test' recompiles each package along with any files with names matching
+the file pattern "*_test.go".
+Files whose names begin with "_" (including "_test.go") or "." are ignored.
+These additional files can contain test functions, benchmark functions, and
+example functions.  See 'go help testfunc' for more.
+Each listed package causes the execution of a separate test binary.
+
+Test files that declare a package with the suffix "_test" will be compiled as a
+separate package, and then linked and run with the main test binary.
+
+By default, go test needs no arguments.  It compiles and tests the package
+with source in the current directory, including tests, and runs the tests.
+
+The package is built in a temporary directory so it does not interfere with the
+non-test installation.
+
+In addition to the build flags, the flags handled by 'go test' itself are:
+
+	-c  Compile the test binary to pkg.test but do not run it.
+	    (Where pkg is the last element of the package's import path.)
+
+	-i
+	    Install packages that are dependencies of the test.
+	    Do not run the test.
+
+	-exec xprog
+	    Run the test binary using xprog. The behavior is the same as
+	    in 'go run'. See 'go help run' for details.
+
+The test binary also accepts flags that control execution of the test; these
+flags are also accessible by 'go test'.  See 'go help testflag' for details.
+
+If the test binary needs any other flags, they should be presented after the
+package names. The go tool treats as a flag the first argument that begins with
+a minus sign that it does not recognize itself; that argument and all subsequent
+arguments are passed as arguments to the test binary.
+
+For more about build flags, see 'go help build'.
+For more about specifying packages, see 'go help packages'.
+
+See also: go build, go vet.
+
+
+Run specified go tool
+
+Usage:
+
+	go tool [-n] command [args...]
+
+Tool runs the go tool command identified by the arguments.
+With no arguments it prints the list of known tools.
+
+The -n flag causes tool to print the command that would be
+executed but not execute it.
+
+For more about each tool command, see 'go tool command -h'.
+
+
+Print Go version
+
+Usage:
+
+	go version
+
+Version prints the Go version, as reported by runtime.Version.
+
+
+Run go tool vet on packages
+
+Usage:
+
+	go vet [-n] [-x] [packages]
+
+Vet runs the Go vet command on the packages named by the import paths.
+
+For more about vet, see 'godoc code.google.com/p/go.tools/cmd/vet'.
+For more about specifying packages, see 'go help packages'.
+
+To run the vet tool with specific options, run 'go tool vet'.
+
+The -n flag prints commands that would be executed.
+The -x flag prints commands as they are executed.
+
+See also: go fmt, go fix.
+
+
+Calling between Go and C
+
+There are two different ways to call between Go and C/C++ code.
+
+The first is the cgo tool, which is part of the Go distribution.  For
+information on how to use it see the cgo documentation (godoc cmd/cgo).
+
+The second is the SWIG program, which is a general tool for
+interfacing between languages.  For information on SWIG see
+http://swig.org/.  When running go build, any file with a .swig
+extension will be passed to SWIG.  Any file with a .swigcxx extension
+will be passed to SWIG with the -c++ option.
+
+When either cgo or SWIG is used, go build will pass any .c, .m, .s,
+or .S files to the C compiler, and any .cc, .cpp, .cxx files to the C++
+compiler.  The CC or CXX environment variables may be set to determine
+the C or C++ compiler, respectively, to use.
+
+
+File types
+
+The go command examines the contents of a restricted set of files
+in each directory. It identifies which files to examine based on
+the extension of the file name. These extensions are:
+
+	.go
+		Go source files.
+	.c, .h
+		C source files.
+		If the package uses cgo, these will be compiled with the
+		OS-native compiler (typically gcc); otherwise they will be
+		compiled with the Go-specific support compiler,
+		5c, 6c, or 8c, etc. as appropriate.
+	.cc, .cpp, .cxx, .hh, .hpp, .hxx
+		C++ source files. Only useful with cgo or SWIG, and always
+		compiled with the OS-native compiler.
+	.m
+		Objective-C source files. Only useful with cgo, and always
+		compiled with the OS-native compiler.
+	.s, .S
+		Assembler source files.
+		If the package uses cgo, these will be assembled with the
+		OS-native assembler (typically gcc (sic)); otherwise they
+		will be assembled with the Go-specific support assembler,
+		5a, 6a, or 8a, etc., as appropriate.
+	.swig, .swigcxx
+		SWIG definition files.
+	.syso
+		System object files.
+
+Files of each of these types except .syso may contain build
+constraints, but the go command stops scanning for build constraints
+at the first item in the file that is not a blank line or //-style
+line comment.
+
+
+GOPATH environment variable
+
+The Go path is used to resolve import statements.
+It is implemented by and documented in the go/build package.
+
+The GOPATH environment variable lists places to look for Go code.
+On Unix, the value is a colon-separated string.
+On Windows, the value is a semicolon-separated string.
+On Plan 9, the value is a list.
+
+GOPATH must be set to get, build and install packages outside the
+standard Go tree.
+
+Each directory listed in GOPATH must have a prescribed structure:
+
+The src/ directory holds source code.  The path below 'src'
+determines the import path or executable name.
+
+The pkg/ directory holds installed package objects.
+As in the Go tree, each target operating system and
+architecture pair has its own subdirectory of pkg
+(pkg/GOOS_GOARCH).
+
+If DIR is a directory listed in the GOPATH, a package with
+source in DIR/src/foo/bar can be imported as "foo/bar" and
+has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a".
+
+The bin/ directory holds compiled commands.
+Each command is named for its source directory, but only
+the final element, not the entire path.  That is, the
+command with source in DIR/src/foo/quux is installed into
+DIR/bin/quux, not DIR/bin/foo/quux.  The foo/ is stripped
+so that you can add DIR/bin to your PATH to get at the
+installed commands.  If the GOBIN environment variable is
+set, commands are installed to the directory it names instead
+of DIR/bin.
+
+Here's an example directory layout:
+
+    GOPATH=/home/user/gocode
+
+    /home/user/gocode/
+        src/
+            foo/
+                bar/               (go code in package bar)
+                    x.go
+                quux/              (go code in package main)
+                    y.go
+        bin/
+            quux                   (installed command)
+        pkg/
+            linux_amd64/
+                foo/
+                    bar.a          (installed package object)
+
+Go searches each directory listed in GOPATH to find source code,
+but new packages are always downloaded into the first directory
+in the list.
+
+
+Import path syntax
+
+An import path (see 'go help packages') denotes a package
+stored in the local file system.  In general, an import path denotes
+either a standard package (such as "unicode/utf8") or a package
+found in one of the work spaces (see 'go help gopath').
+
+Relative import paths
+
+An import path beginning with ./ or ../ is called a relative path.
+The toolchain supports relative import paths as a shortcut in two ways.
+
+First, a relative path can be used as a shorthand on the command line.
+If you are working in the directory containing the code imported as
+"unicode" and want to run the tests for "unicode/utf8", you can type
+"go test ./utf8" instead of needing to specify the full path.
+Similarly, in the reverse situation, "go test .." will test "unicode" from
+the "unicode/utf8" directory. Relative patterns are also allowed, like
+"go test ./..." to test all subdirectories. See 'go help packages' for details
+on the pattern syntax.
+
+Second, if you are compiling a Go program not in a work space,
+you can use a relative path in an import statement in that program
+to refer to nearby code also not in a work space.
+This makes it easy to experiment with small multipackage programs
+outside of the usual work spaces, but such programs cannot be
+installed with "go install" (there is no work space in which to install them),
+so they are rebuilt from scratch each time they are built.
+To avoid ambiguity, Go programs cannot use relative import paths
+within a work space.
+
+Remote import paths
+
+Certain import paths also
+describe how to obtain the source code for the package using
+a revision control system.
+
+A few common code hosting sites have special syntax:
+
+	Bitbucket (Git, Mercurial)
+
+		import "bitbucket.org/user/project"
+		import "bitbucket.org/user/project/sub/directory"
+
+	GitHub (Git)
+
+		import "github.com/user/project"
+		import "github.com/user/project/sub/directory"
+
+	Google Code Project Hosting (Git, Mercurial, Subversion)
+
+		import "code.google.com/p/project"
+		import "code.google.com/p/project/sub/directory"
+
+		import "code.google.com/p/project.subrepository"
+		import "code.google.com/p/project.subrepository/sub/directory"
+
+	Launchpad (Bazaar)
+
+		import "launchpad.net/project"
+		import "launchpad.net/project/series"
+		import "launchpad.net/project/series/sub/directory"
+
+		import "launchpad.net/~user/project/branch"
+		import "launchpad.net/~user/project/branch/sub/directory"
+
+For code hosted on other servers, import paths may either be qualified
+with the version control type, or the go tool can dynamically fetch
+the import path over https/http and discover where the code resides
+from a <meta> tag in the HTML.
+
+To declare the code location, an import path of the form
+
+	repository.vcs/path
+
+specifies the given repository, with or without the .vcs suffix,
+using the named version control system, and then the path inside
+that repository.  The supported version control systems are:
+
+	Bazaar      .bzr
+	Git         .git
+	Mercurial   .hg
+	Subversion  .svn
+
+For example,
+
+	import "example.org/user/foo.hg"
+
+denotes the root directory of the Mercurial repository at
+example.org/user/foo or foo.hg, and
+
+	import "example.org/repo.git/foo/bar"
+
+denotes the foo/bar directory of the Git repository at
+example.org/repo or repo.git.
+
+When a version control system supports multiple protocols,
+each is tried in turn when downloading.  For example, a Git
+download tries git://, then https://, then http://.
+
+If the import path is not a known code hosting site and also lacks a
+version control qualifier, the go tool attempts to fetch the import
+over https/http and looks for a <meta> tag in the document's HTML
+<head>.
+
+The meta tag has the form:
+
+	<meta name="go-import" content="import-prefix vcs repo-root">
+
+The import-prefix is the import path corresponding to the repository
+root. It must be a prefix or an exact match of the package being
+fetched with "go get". If it's not an exact match, another http
+request is made at the prefix to verify the <meta> tags match.
+
+The vcs is one of "git", "hg", "svn", etc,
+
+The repo-root is the root of the version control system
+containing a scheme and not containing a .vcs qualifier.
+
+For example,
+
+	import "example.org/pkg/foo"
+
+will result in the following request(s):
+
+	https://example.org/pkg/foo?go-get=1 (preferred)
+	http://example.org/pkg/foo?go-get=1  (fallback)
+
+If that page contains the meta tag
+
+	<meta name="go-import" content="example.org git https://code.org/r/p/exproj">
+
+the go tool will verify that https://example.org/?go-get=1 contains the
+same meta tag and then git clone https://code.org/r/p/exproj into
+GOPATH/src/example.org.
+
+New downloaded packages are written to the first directory
+listed in the GOPATH environment variable (see 'go help gopath').
+
+The go command attempts to download the version of the
+package appropriate for the Go release being used.
+Run 'go help install' for more.
+
+
+Description of package lists
+
+Many commands apply to a set of packages:
+
+	go action [packages]
+
+Usually, [packages] is a list of import paths.
+
+An import path that is a rooted path or that begins with
+a . or .. element is interpreted as a file system path and
+denotes the package in that directory.
+
+Otherwise, the import path P denotes the package found in
+the directory DIR/src/P for some DIR listed in the GOPATH
+environment variable (see 'go help gopath').
+
+If no import paths are given, the action applies to the
+package in the current directory.
+
+There are three reserved names for paths that should not be used
+for packages to be built with the go tool:
+
+- "main" denotes the top-level package in a stand-alone executable.
+
+- "all" expands to all package directories found in all the GOPATH
+trees. For example, 'go list all' lists all the packages on the local
+system.
+
+- "std" is like all but expands to just the packages in the standard
+Go library.
+
+An import path is a pattern if it includes one or more "..." wildcards,
+each of which can match any string, including the empty string and
+strings containing slashes.  Such a pattern expands to all package
+directories found in the GOPATH trees with names matching the
+patterns.  As a special case, x/... matches x as well as x's subdirectories.
+For example, net/... expands to net and packages in its subdirectories.
+
+An import path can also name a package to be downloaded from
+a remote repository.  Run 'go help importpath' for details.
+
+Every package in a program must have a unique import path.
+By convention, this is arranged by starting each path with a
+unique prefix that belongs to you.  For example, paths used
+internally at Google all begin with 'google', and paths
+denoting remote repositories begin with the path to the code,
+such as 'code.google.com/p/project'.
+
+As a special case, if the package list is a list of .go files from a
+single directory, the command is applied to a single synthesized
+package made up of exactly those files, ignoring any build constraints
+in those files and ignoring any other files in the directory.
+
+File names that begin with "." or "_" are ignored by the go tool.
+
+
+Description of testing flags
+
+The 'go test' command takes both flags that apply to 'go test' itself
+and flags that apply to the resulting test binary.
+
+Several of the flags control profiling and write an execution profile
+suitable for "go tool pprof"; run "go tool pprof help" for more
+information.  The --alloc_space, --alloc_objects, and --show_bytes
+options of pprof control how the information is presented.
+
+The following flags are recognized by the 'go test' command and
+control the execution of any test:
+
+	-bench regexp
+	    Run benchmarks matching the regular expression.
+	    By default, no benchmarks run. To run all benchmarks,
+	    use '-bench .' or '-bench=.'.
+
+	-benchmem
+	    Print memory allocation statistics for benchmarks.
+
+	-benchtime t
+	    Run enough iterations of each benchmark to take t, specified
+	    as a time.Duration (for example, -benchtime 1h30s).
+	    The default is 1 second (1s).
+
+	-blockprofile block.out
+	    Write a goroutine blocking profile to the specified file
+	    when all tests are complete.
+
+	-blockprofilerate n
+	    Control the detail provided in goroutine blocking profiles by
+	    calling runtime.SetBlockProfileRate with n.
+	    See 'godoc runtime SetBlockProfileRate'.
+	    The profiler aims to sample, on average, one blocking event every
+	    n nanoseconds the program spends blocked.  By default,
+	    if -test.blockprofile is set without this flag, all blocking events
+	    are recorded, equivalent to -test.blockprofilerate=1.
+
+	-cover
+	    Enable coverage analysis.
+
+	-covermode set,count,atomic
+	    Set the mode for coverage analysis for the package[s]
+	    being tested. The default is "set" unless -race is enabled,
+	    in which case it is "atomic".
+	    The values:
+		set: bool: does this statement run?
+		count: int: how many times does this statement run?
+		atomic: int: count, but correct in multithreaded tests;
+			significantly more expensive.
+	    Sets -cover.
+
+	-coverpkg pkg1,pkg2,pkg3
+	    Apply coverage analysis in each test to the given list of packages.
+	    The default is for each test to analyze only the package being tested.
+	    Packages are specified as import paths.
+	    Sets -cover.
+
+	-coverprofile cover.out
+	    Write a coverage profile to the specified file after all tests
+	    have passed.
+	    Sets -cover.
+
+	-cpu 1,2,4
+	    Specify a list of GOMAXPROCS values for which the tests or
+	    benchmarks should be executed.  The default is the current value
+	    of GOMAXPROCS.
+
+	-cpuprofile cpu.out
+	    Write a CPU profile to the specified file before exiting.
+
+	-memprofile mem.out
+	    Write a memory profile to the specified file after all tests
+	    have passed.
+
+	-memprofilerate n
+	    Enable more precise (and expensive) memory profiles by setting
+	    runtime.MemProfileRate.  See 'godoc runtime MemProfileRate'.
+	    To profile all memory allocations, use -test.memprofilerate=1
+	    and pass --alloc_space flag to the pprof tool.
+
+	-outputdir directory
+	    Place output files from profiling in the specified directory,
+	    by default the directory in which "go test" is running.
+
+	-parallel n
+	    Allow parallel execution of test functions that call t.Parallel.
+	    The value of this flag is the maximum number of tests to run
+	    simultaneously; by default, it is set to the value of GOMAXPROCS.
+
+	-run regexp
+	    Run only those tests and examples matching the regular
+	    expression.
+
+	-short
+	    Tell long-running tests to shorten their run time.
+	    It is off by default but set during all.bash so that installing
+	    the Go tree can run a sanity check but not spend time running
+	    exhaustive tests.
+
+	-timeout t
+	    If a test runs longer than t, panic.
+
+	-v
+	    Verbose output: log all tests as they are run. Also print all
+	    text from Log and Logf calls even if the test succeeds.
+
+The test binary, called pkg.test where pkg is the name of the
+directory containing the package sources, can be invoked directly
+after building it with 'go test -c'. When invoking the test binary
+directly, each of the standard flag names must be prefixed with 'test.',
+as in -test.run=TestMyFunc or -test.v.
+
+When running 'go test', flags not listed above are passed through
+unaltered. For instance, the command
+
+	go test -x -v -cpuprofile=prof.out -dir=testdata -update
+
+will compile the test binary and then run it as
+
+	pkg.test -test.v -test.cpuprofile=prof.out -dir=testdata -update
+
+The test flags that generate profiles (other than for coverage) also
+leave the test binary in pkg.test for use when analyzing the profiles.
+
+Flags not recognized by 'go test' must be placed after any specified packages.
+
+
+Description of testing functions
+
+The 'go test' command expects to find test, benchmark, and example functions
+in the "*_test.go" files corresponding to the package under test.
+
+A test function is one named TestXXX (where XXX is any alphanumeric string
+not starting with a lower case letter) and should have the signature,
+
+	func TestXXX(t *testing.T) { ... }
+
+A benchmark function is one named BenchmarkXXX and should have the signature,
+
+	func BenchmarkXXX(b *testing.B) { ... }
+
+An example function is similar to a test function but, instead of using
+*testing.T to report success or failure, prints output to os.Stdout.
+That output is compared against the function's "Output:" comment, which
+must be the last comment in the function body (see example below). An
+example with no such comment, or with no text after "Output:" is compiled
+but not executed.
+
+Godoc displays the body of ExampleXXX to demonstrate the use
+of the function, constant, or variable XXX.  An example of a method M with
+receiver type T or *T is named ExampleT_M.  There may be multiple examples
+for a given function, constant, or variable, distinguished by a trailing _xxx,
+where xxx is a suffix not beginning with an upper case letter.
+
+Here is an example of an example:
+
+	func ExamplePrintln() {
+		Println("The output of\nthis example.")
+		// Output: The output of
+		// this example.
+	}
+
+The entire test file is presented as the example when it contains a single
+example function, at least one other function, type, variable, or constant
+declaration, and no test or benchmark functions.
+
+See the documentation of the testing package for more information.
+
+
+*/
+package main
diff --git a/third_party/gofrontend/libgo/go/cmd/go/env.go b/third_party/gofrontend/libgo/go/cmd/go/env.go
new file mode 100644
index 0000000..26d37df
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/env.go
@@ -0,0 +1,112 @@
+// 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 main
+
+import (
+	"fmt"
+	"os"
+	"runtime"
+	"strings"
+)
+
+var cmdEnv = &Command{
+	Run:       runEnv,
+	UsageLine: "env [var ...]",
+	Short:     "print Go environment information",
+	Long: `
+Env prints Go environment information.
+
+By default env prints information as a shell script
+(on Windows, a batch file).  If one or more variable
+names is given as arguments,  env prints the value of
+each named variable on its own line.
+	`,
+}
+
+type envVar struct {
+	name, value string
+}
+
+func mkEnv() []envVar {
+	var b builder
+	b.init()
+
+	env := []envVar{
+		{"GOARCH", goarch},
+		{"GOBIN", gobin},
+		{"GOCHAR", archChar},
+		{"GOEXE", exeSuffix},
+		{"GOHOSTARCH", runtime.GOARCH},
+		{"GOHOSTOS", runtime.GOOS},
+		{"GOOS", goos},
+		{"GOPATH", os.Getenv("GOPATH")},
+		{"GORACE", os.Getenv("GORACE")},
+		{"GOROOT", goroot},
+		{"GOTOOLDIR", toolDir},
+
+		// disable escape codes in clang errors
+		{"TERM", "dumb"},
+	}
+
+	if goos != "plan9" {
+		cmd := b.gccCmd(".")
+		env = append(env, envVar{"CC", cmd[0]})
+		env = append(env, envVar{"GOGCCFLAGS", strings.Join(cmd[3:], " ")})
+		cmd = b.gxxCmd(".")
+		env = append(env, envVar{"CXX", cmd[0]})
+	}
+
+	if buildContext.CgoEnabled {
+		env = append(env, envVar{"CGO_ENABLED", "1"})
+	} else {
+		env = append(env, envVar{"CGO_ENABLED", "0"})
+	}
+
+	return env
+}
+
+func findEnv(env []envVar, name string) string {
+	for _, e := range env {
+		if e.name == name {
+			return e.value
+		}
+	}
+	return ""
+}
+
+func runEnv(cmd *Command, args []string) {
+	env := mkEnv()
+	if len(args) > 0 {
+		for _, name := range args {
+			fmt.Printf("%s\n", findEnv(env, name))
+		}
+		return
+	}
+
+	for _, e := range env {
+		if e.name != "TERM" {
+			switch runtime.GOOS {
+			default:
+				fmt.Printf("%s=\"%s\"\n", e.name, e.value)
+			case "plan9":
+				if strings.IndexByte(e.value, '\x00') < 0 {
+					fmt.Printf("%s='%s'\n", e.name, strings.Replace(e.value, "'", "''", -1))
+				} else {
+					v := strings.Split(e.value, "\x00")
+					fmt.Printf("%s=(", e.name)
+					for x, s := range v {
+						if x > 0 {
+							fmt.Printf(" ")
+						}
+						fmt.Printf("%s", s)
+					}
+					fmt.Printf(")\n")
+				}
+			case "windows":
+				fmt.Printf("set %s=%s\n", e.name, e.value)
+			}
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/fix.go b/third_party/gofrontend/libgo/go/cmd/go/fix.go
new file mode 100644
index 0000000..8736cce
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/fix.go
@@ -0,0 +1,30 @@
+// Copyright 2011 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
+
+var cmdFix = &Command{
+	Run:       runFix,
+	UsageLine: "fix [packages]",
+	Short:     "run go tool fix on packages",
+	Long: `
+Fix runs the Go fix command on the packages named by the import paths.
+
+For more about fix, see 'godoc fix'.
+For more about specifying packages, see 'go help packages'.
+
+To run fix with specific options, run 'go tool fix'.
+
+See also: go fmt, go vet.
+	`,
+}
+
+func runFix(cmd *Command, args []string) {
+	for _, pkg := range packages(args) {
+		// Use pkg.gofiles instead of pkg.Dir so that
+		// the command only applies to this package,
+		// not to packages in subdirectories.
+		run(stringList(tool("fix"), relPaths(pkg.allgofiles)))
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/fmt.go b/third_party/gofrontend/libgo/go/cmd/go/fmt.go
new file mode 100644
index 0000000..65dc3ca
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/fmt.go
@@ -0,0 +1,38 @@
+// Copyright 2011 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
+
+func init() {
+	addBuildFlagsNX(cmdFmt)
+}
+
+var cmdFmt = &Command{
+	Run:       runFmt,
+	UsageLine: "fmt [-n] [-x] [packages]",
+	Short:     "run gofmt on package sources",
+	Long: `
+Fmt runs the command 'gofmt -l -w' on the packages named
+by the import paths.  It prints the names of the files that are modified.
+
+For more about gofmt, see 'godoc gofmt'.
+For more about specifying packages, see 'go help packages'.
+
+The -n flag prints commands that would be executed.
+The -x flag prints commands as they are executed.
+
+To run gofmt with specific options, run gofmt itself.
+
+See also: go fix, go vet.
+	`,
+}
+
+func runFmt(cmd *Command, args []string) {
+	for _, pkg := range packages(args) {
+		// Use pkg.gofiles instead of pkg.Dir so that
+		// the command only applies to this package,
+		// not to packages in subdirectories.
+		run(stringList("gofmt", "-l", "-w", relPaths(pkg.allgofiles)))
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/get.go b/third_party/gofrontend/libgo/go/cmd/go/get.go
new file mode 100644
index 0000000..e708fcf
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/get.go
@@ -0,0 +1,429 @@
+// Copyright 2011 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"
+	"go/build"
+	"os"
+	"path/filepath"
+	"regexp"
+	"runtime"
+	"strconv"
+	"strings"
+)
+
+var cmdGet = &Command{
+	UsageLine: "get [-d] [-fix] [-t] [-u] [build flags] [packages]",
+	Short:     "download and install packages and dependencies",
+	Long: `
+Get downloads and installs the packages named by the import paths,
+along with their dependencies.
+
+The -d flag instructs get to stop after downloading the packages; that is,
+it instructs get not to install the packages.
+
+The -fix flag instructs get to run the fix tool on the downloaded packages
+before resolving dependencies or building the code.
+
+The -t flag instructs get to also download the packages required to build
+the tests for the specified packages.
+
+The -u flag instructs get to use the network to update the named packages
+and their dependencies.  By default, get uses the network to check out
+missing packages but does not use it to look for updates to existing packages.
+
+Get also accepts build flags to control the installation. See 'go help build'.
+
+When checking out or updating a package, get looks for a branch or tag
+that matches the locally installed version of Go. The most important
+rule is that if the local installation is running version "go1", get
+searches for a branch or tag named "go1". If no such version exists it
+retrieves the most recent version of the package.
+
+For more about specifying packages, see 'go help packages'.
+
+For more about how 'go get' finds source code to
+download, see 'go help importpath'.
+
+See also: go build, go install, go clean.
+	`,
+}
+
+var getD = cmdGet.Flag.Bool("d", false, "")
+var getT = cmdGet.Flag.Bool("t", false, "")
+var getU = cmdGet.Flag.Bool("u", false, "")
+var getFix = cmdGet.Flag.Bool("fix", false, "")
+
+func init() {
+	addBuildFlags(cmdGet)
+	cmdGet.Run = runGet // break init loop
+}
+
+func runGet(cmd *Command, args []string) {
+	// Phase 1.  Download/update.
+	var stk importStack
+	for _, arg := range downloadPaths(args) {
+		download(arg, &stk, *getT)
+	}
+	exitIfErrors()
+
+	// Phase 2. Rescan packages and re-evaluate args list.
+
+	// Code we downloaded and all code that depends on it
+	// needs to be evicted from the package cache so that
+	// the information will be recomputed.  Instead of keeping
+	// track of the reverse dependency information, evict
+	// everything.
+	for name := range packageCache {
+		delete(packageCache, name)
+	}
+
+	args = importPaths(args)
+
+	// Phase 3.  Install.
+	if *getD {
+		// Download only.
+		// Check delayed until now so that importPaths
+		// has a chance to print errors.
+		return
+	}
+
+	runInstall(cmd, args)
+}
+
+// downloadPaths prepares the list of paths to pass to download.
+// It expands ... patterns that can be expanded.  If there is no match
+// for a particular pattern, downloadPaths leaves it in the result list,
+// in the hope that we can figure out the repository from the
+// initial ...-free prefix.
+func downloadPaths(args []string) []string {
+	args = importPathsNoDotExpansion(args)
+	var out []string
+	for _, a := range args {
+		if strings.Contains(a, "...") {
+			var expand []string
+			// Use matchPackagesInFS to avoid printing
+			// warnings.  They will be printed by the
+			// eventual call to importPaths instead.
+			if build.IsLocalImport(a) {
+				expand = matchPackagesInFS(a)
+			} else {
+				expand = matchPackages(a)
+			}
+			if len(expand) > 0 {
+				out = append(out, expand...)
+				continue
+			}
+		}
+		out = append(out, a)
+	}
+	return out
+}
+
+// downloadCache records the import paths we have already
+// considered during the download, to avoid duplicate work when
+// there is more than one dependency sequence leading to
+// a particular package.
+var downloadCache = map[string]bool{}
+
+// downloadRootCache records the version control repository
+// root directories we have already considered during the download.
+// For example, all the packages in the code.google.com/p/codesearch repo
+// share the same root (the directory for that path), and we only need
+// to run the hg commands to consider each repository once.
+var downloadRootCache = map[string]bool{}
+
+// download runs the download half of the get command
+// for the package named by the argument.
+func download(arg string, stk *importStack, getTestDeps bool) {
+	p := loadPackage(arg, stk)
+	if p.Error != nil && p.Error.hard {
+		errorf("%s", p.Error)
+		return
+	}
+
+	// There's nothing to do if this is a package in the standard library.
+	if p.Standard {
+		return
+	}
+
+	// Only process each package once.
+	if downloadCache[arg] {
+		return
+	}
+	downloadCache[arg] = true
+
+	pkgs := []*Package{p}
+	wildcardOkay := len(*stk) == 0
+	isWildcard := false
+
+	// Download if the package is missing, or update if we're using -u.
+	if p.Dir == "" || *getU {
+		// The actual download.
+		stk.push(p.ImportPath)
+		err := downloadPackage(p)
+		if err != nil {
+			errorf("%s", &PackageError{ImportStack: stk.copy(), Err: err.Error()})
+			stk.pop()
+			return
+		}
+
+		args := []string{arg}
+		// If the argument has a wildcard in it, re-evaluate the wildcard.
+		// We delay this until after reloadPackage so that the old entry
+		// for p has been replaced in the package cache.
+		if wildcardOkay && strings.Contains(arg, "...") {
+			if build.IsLocalImport(arg) {
+				args = matchPackagesInFS(arg)
+			} else {
+				args = matchPackages(arg)
+			}
+			isWildcard = true
+		}
+
+		// Clear all relevant package cache entries before
+		// doing any new loads.
+		for _, arg := range args {
+			p := packageCache[arg]
+			if p != nil {
+				delete(packageCache, p.Dir)
+				delete(packageCache, p.ImportPath)
+			}
+		}
+
+		pkgs = pkgs[:0]
+		for _, arg := range args {
+			stk.push(arg)
+			p := loadPackage(arg, stk)
+			stk.pop()
+			if p.Error != nil {
+				errorf("%s", p.Error)
+				continue
+			}
+			pkgs = append(pkgs, p)
+		}
+	}
+
+	// Process package, which might now be multiple packages
+	// due to wildcard expansion.
+	for _, p := range pkgs {
+		if *getFix {
+			run(stringList(tool("fix"), relPaths(p.allgofiles)))
+
+			// The imports might have changed, so reload again.
+			p = reloadPackage(arg, stk)
+			if p.Error != nil {
+				errorf("%s", p.Error)
+				return
+			}
+		}
+
+		if isWildcard {
+			// Report both the real package and the
+			// wildcard in any error message.
+			stk.push(p.ImportPath)
+		}
+
+		// Process dependencies, now that we know what they are.
+		for _, dep := range p.deps {
+			// Don't get test dependencies recursively.
+			download(dep.ImportPath, stk, false)
+		}
+		if getTestDeps {
+			// Process test dependencies when -t is specified.
+			// (Don't get test dependencies for test dependencies.)
+			for _, path := range p.TestImports {
+				download(path, stk, false)
+			}
+			for _, path := range p.XTestImports {
+				download(path, stk, false)
+			}
+		}
+
+		if isWildcard {
+			stk.pop()
+		}
+	}
+}
+
+// downloadPackage runs the create or download command
+// to make the first copy of or update a copy of the given package.
+func downloadPackage(p *Package) error {
+	var (
+		vcs            *vcsCmd
+		repo, rootPath string
+		err            error
+	)
+	if p.build.SrcRoot != "" {
+		// Directory exists.  Look for checkout along path to src.
+		vcs, rootPath, err = vcsForDir(p)
+		if err != nil {
+			return err
+		}
+		repo = "<local>" // should be unused; make distinctive
+	} else {
+		// Analyze the import path to determine the version control system,
+		// repository, and the import path for the root of the repository.
+		rr, err := repoRootForImportPath(p.ImportPath)
+		if err != nil {
+			return err
+		}
+		vcs, repo, rootPath = rr.vcs, rr.repo, rr.root
+	}
+
+	if p.build.SrcRoot == "" {
+		// Package not found.  Put in first directory of $GOPATH.
+		list := filepath.SplitList(buildContext.GOPATH)
+		if len(list) == 0 {
+			return fmt.Errorf("cannot download, $GOPATH not set. For more details see: go help gopath")
+		}
+		// Guard against people setting GOPATH=$GOROOT.
+		if list[0] == goroot {
+			return fmt.Errorf("cannot download, $GOPATH must not be set to $GOROOT. For more details see: go help gopath")
+		}
+		p.build.SrcRoot = filepath.Join(list[0], "src")
+		p.build.PkgRoot = filepath.Join(list[0], "pkg")
+	}
+	root := filepath.Join(p.build.SrcRoot, rootPath)
+	// If we've considered this repository already, don't do it again.
+	if downloadRootCache[root] {
+		return nil
+	}
+	downloadRootCache[root] = true
+
+	if buildV {
+		fmt.Fprintf(os.Stderr, "%s (download)\n", rootPath)
+	}
+
+	// Check that this is an appropriate place for the repo to be checked out.
+	// The target directory must either not exist or have a repo checked out already.
+	meta := filepath.Join(root, "."+vcs.cmd)
+	st, err := os.Stat(meta)
+	if err == nil && !st.IsDir() {
+		return fmt.Errorf("%s exists but is not a directory", meta)
+	}
+	if err != nil {
+		// Metadata directory does not exist.  Prepare to checkout new copy.
+		// Some version control tools require the target directory not to exist.
+		// We require that too, just to avoid stepping on existing work.
+		if _, err := os.Stat(root); err == nil {
+			return fmt.Errorf("%s exists but %s does not - stale checkout?", root, meta)
+		}
+		// Some version control tools require the parent of the target to exist.
+		parent, _ := filepath.Split(root)
+		if err = os.MkdirAll(parent, 0777); err != nil {
+			return err
+		}
+		if err = vcs.create(root, repo); err != nil {
+			return err
+		}
+	} else {
+		// Metadata directory does exist; download incremental updates.
+		if err = vcs.download(root); err != nil {
+			return err
+		}
+	}
+
+	if buildN {
+		// Do not show tag sync in -n; it's noise more than anything,
+		// and since we're not running commands, no tag will be found.
+		// But avoid printing nothing.
+		fmt.Fprintf(os.Stderr, "# cd %s; %s sync/update\n", root, vcs.cmd)
+		return nil
+	}
+
+	// Select and sync to appropriate version of the repository.
+	tags, err := vcs.tags(root)
+	if err != nil {
+		return err
+	}
+	vers := runtime.Version()
+	if i := strings.Index(vers, " "); i >= 0 {
+		vers = vers[:i]
+	}
+	if err := vcs.tagSync(root, selectTag(vers, tags)); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// goTag matches go release tags such as go1 and go1.2.3.
+// The numbers involved must be small (at most 4 digits),
+// have no unnecessary leading zeros, and the version cannot
+// end in .0 - it is go1, not go1.0 or go1.0.0.
+var goTag = regexp.MustCompile(
+	`^go((0|[1-9][0-9]{0,3})\.)*([1-9][0-9]{0,3})$`,
+)
+
+// selectTag returns the closest matching tag for a given version.
+// Closest means the latest one that is not after the current release.
+// Version "goX" (or "goX.Y" or "goX.Y.Z") matches tags of the same form.
+// Version "release.rN" matches tags of the form "go.rN" (N being a floating-point number).
+// Version "weekly.YYYY-MM-DD" matches tags like "go.weekly.YYYY-MM-DD".
+//
+// NOTE(rsc): Eventually we will need to decide on some logic here.
+// For now, there is only "go1".  This matches the docs in go help get.
+func selectTag(goVersion string, tags []string) (match string) {
+	for _, t := range tags {
+		if t == "go1" {
+			return "go1"
+		}
+	}
+	return ""
+
+	/*
+		if goTag.MatchString(goVersion) {
+			v := goVersion
+			for _, t := range tags {
+				if !goTag.MatchString(t) {
+					continue
+				}
+				if cmpGoVersion(match, t) < 0 && cmpGoVersion(t, v) <= 0 {
+					match = t
+				}
+			}
+		}
+
+		return match
+	*/
+}
+
+// cmpGoVersion returns -1, 0, +1 reporting whether
+// x < y, x == y, or x > y.
+func cmpGoVersion(x, y string) int {
+	// Malformed strings compare less than well-formed strings.
+	if !goTag.MatchString(x) {
+		return -1
+	}
+	if !goTag.MatchString(y) {
+		return +1
+	}
+
+	// Compare numbers in sequence.
+	xx := strings.Split(x[len("go"):], ".")
+	yy := strings.Split(y[len("go"):], ".")
+
+	for i := 0; i < len(xx) && i < len(yy); i++ {
+		// The Atoi are guaranteed to succeed
+		// because the versions match goTag.
+		xi, _ := strconv.Atoi(xx[i])
+		yi, _ := strconv.Atoi(yy[i])
+		if xi < yi {
+			return -1
+		} else if xi > yi {
+			return +1
+		}
+	}
+
+	if len(xx) < len(yy) {
+		return -1
+	}
+	if len(xx) > len(yy) {
+		return +1
+	}
+	return 0
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/go11.go b/third_party/gofrontend/libgo/go/cmd/go/go11.go
new file mode 100644
index 0000000..8a434df
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/go11.go
@@ -0,0 +1,10 @@
+// Copyright 2013 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 go1.1
+
+package main
+
+// Test that go1.1 tag above is included in builds. main.go refers to this definition.
+const go11tag = true
diff --git a/third_party/gofrontend/libgo/go/cmd/go/help.go b/third_party/gofrontend/libgo/go/cmd/go/help.go
new file mode 100644
index 0000000..40da7e1
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/help.go
@@ -0,0 +1,337 @@
+// Copyright 2011 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
+
+var helpC = &Command{
+	UsageLine: "c",
+	Short:     "calling between Go and C",
+	Long: `
+There are two different ways to call between Go and C/C++ code.
+
+The first is the cgo tool, which is part of the Go distribution.  For
+information on how to use it see the cgo documentation (godoc cmd/cgo).
+
+The second is the SWIG program, which is a general tool for
+interfacing between languages.  For information on SWIG see
+http://swig.org/.  When running go build, any file with a .swig
+extension will be passed to SWIG.  Any file with a .swigcxx extension
+will be passed to SWIG with the -c++ option.
+
+When either cgo or SWIG is used, go build will pass any .c, .m, .s,
+or .S files to the C compiler, and any .cc, .cpp, .cxx files to the C++
+compiler.  The CC or CXX environment variables may be set to determine
+the C or C++ compiler, respectively, to use.
+	`,
+}
+
+var helpPackages = &Command{
+	UsageLine: "packages",
+	Short:     "description of package lists",
+	Long: `
+Many commands apply to a set of packages:
+
+	go action [packages]
+
+Usually, [packages] is a list of import paths.
+
+An import path that is a rooted path or that begins with
+a . or .. element is interpreted as a file system path and
+denotes the package in that directory.
+
+Otherwise, the import path P denotes the package found in
+the directory DIR/src/P for some DIR listed in the GOPATH
+environment variable (see 'go help gopath').
+
+If no import paths are given, the action applies to the
+package in the current directory.
+
+There are three reserved names for paths that should not be used
+for packages to be built with the go tool:
+
+- "main" denotes the top-level package in a stand-alone executable.
+
+- "all" expands to all package directories found in all the GOPATH
+trees. For example, 'go list all' lists all the packages on the local
+system.
+
+- "std" is like all but expands to just the packages in the standard
+Go library.
+
+An import path is a pattern if it includes one or more "..." wildcards,
+each of which can match any string, including the empty string and
+strings containing slashes.  Such a pattern expands to all package
+directories found in the GOPATH trees with names matching the
+patterns.  As a special case, x/... matches x as well as x's subdirectories.
+For example, net/... expands to net and packages in its subdirectories.
+
+An import path can also name a package to be downloaded from
+a remote repository.  Run 'go help importpath' for details.
+
+Every package in a program must have a unique import path.
+By convention, this is arranged by starting each path with a
+unique prefix that belongs to you.  For example, paths used
+internally at Google all begin with 'google', and paths
+denoting remote repositories begin with the path to the code,
+such as 'code.google.com/p/project'.
+
+As a special case, if the package list is a list of .go files from a
+single directory, the command is applied to a single synthesized
+package made up of exactly those files, ignoring any build constraints
+in those files and ignoring any other files in the directory.
+
+File names that begin with "." or "_" are ignored by the go tool.
+	`,
+}
+
+var helpImportPath = &Command{
+	UsageLine: "importpath",
+	Short:     "import path syntax",
+	Long: `
+
+An import path (see 'go help packages') denotes a package
+stored in the local file system.  In general, an import path denotes
+either a standard package (such as "unicode/utf8") or a package
+found in one of the work spaces (see 'go help gopath').
+
+Relative import paths
+
+An import path beginning with ./ or ../ is called a relative path.
+The toolchain supports relative import paths as a shortcut in two ways.
+
+First, a relative path can be used as a shorthand on the command line.
+If you are working in the directory containing the code imported as
+"unicode" and want to run the tests for "unicode/utf8", you can type
+"go test ./utf8" instead of needing to specify the full path.
+Similarly, in the reverse situation, "go test .." will test "unicode" from
+the "unicode/utf8" directory. Relative patterns are also allowed, like
+"go test ./..." to test all subdirectories. See 'go help packages' for details
+on the pattern syntax.
+
+Second, if you are compiling a Go program not in a work space,
+you can use a relative path in an import statement in that program
+to refer to nearby code also not in a work space.
+This makes it easy to experiment with small multipackage programs
+outside of the usual work spaces, but such programs cannot be
+installed with "go install" (there is no work space in which to install them),
+so they are rebuilt from scratch each time they are built.
+To avoid ambiguity, Go programs cannot use relative import paths
+within a work space.
+
+Remote import paths
+
+Certain import paths also
+describe how to obtain the source code for the package using
+a revision control system.
+
+A few common code hosting sites have special syntax:
+
+	Bitbucket (Git, Mercurial)
+
+		import "bitbucket.org/user/project"
+		import "bitbucket.org/user/project/sub/directory"
+
+	GitHub (Git)
+
+		import "github.com/user/project"
+		import "github.com/user/project/sub/directory"
+
+	Google Code Project Hosting (Git, Mercurial, Subversion)
+
+		import "code.google.com/p/project"
+		import "code.google.com/p/project/sub/directory"
+
+		import "code.google.com/p/project.subrepository"
+		import "code.google.com/p/project.subrepository/sub/directory"
+
+	Launchpad (Bazaar)
+
+		import "launchpad.net/project"
+		import "launchpad.net/project/series"
+		import "launchpad.net/project/series/sub/directory"
+
+		import "launchpad.net/~user/project/branch"
+		import "launchpad.net/~user/project/branch/sub/directory"
+
+For code hosted on other servers, import paths may either be qualified
+with the version control type, or the go tool can dynamically fetch
+the import path over https/http and discover where the code resides
+from a <meta> tag in the HTML.
+
+To declare the code location, an import path of the form
+
+	repository.vcs/path
+
+specifies the given repository, with or without the .vcs suffix,
+using the named version control system, and then the path inside
+that repository.  The supported version control systems are:
+
+	Bazaar      .bzr
+	Git         .git
+	Mercurial   .hg
+	Subversion  .svn
+
+For example,
+
+	import "example.org/user/foo.hg"
+
+denotes the root directory of the Mercurial repository at
+example.org/user/foo or foo.hg, and
+
+	import "example.org/repo.git/foo/bar"
+
+denotes the foo/bar directory of the Git repository at
+example.org/repo or repo.git.
+
+When a version control system supports multiple protocols,
+each is tried in turn when downloading.  For example, a Git
+download tries git://, then https://, then http://.
+
+If the import path is not a known code hosting site and also lacks a
+version control qualifier, the go tool attempts to fetch the import
+over https/http and looks for a <meta> tag in the document's HTML
+<head>.
+
+The meta tag has the form:
+
+	<meta name="go-import" content="import-prefix vcs repo-root">
+
+The import-prefix is the import path corresponding to the repository
+root. It must be a prefix or an exact match of the package being
+fetched with "go get". If it's not an exact match, another http
+request is made at the prefix to verify the <meta> tags match.
+
+The vcs is one of "git", "hg", "svn", etc,
+
+The repo-root is the root of the version control system
+containing a scheme and not containing a .vcs qualifier.
+
+For example,
+
+	import "example.org/pkg/foo"
+
+will result in the following request(s):
+
+	https://example.org/pkg/foo?go-get=1 (preferred)
+	http://example.org/pkg/foo?go-get=1  (fallback)
+
+If that page contains the meta tag
+
+	<meta name="go-import" content="example.org git https://code.org/r/p/exproj">
+
+the go tool will verify that https://example.org/?go-get=1 contains the
+same meta tag and then git clone https://code.org/r/p/exproj into
+GOPATH/src/example.org.
+
+New downloaded packages are written to the first directory
+listed in the GOPATH environment variable (see 'go help gopath').
+
+The go command attempts to download the version of the
+package appropriate for the Go release being used.
+Run 'go help install' for more.
+	`,
+}
+
+var helpGopath = &Command{
+	UsageLine: "gopath",
+	Short:     "GOPATH environment variable",
+	Long: `
+The Go path is used to resolve import statements.
+It is implemented by and documented in the go/build package.
+
+The GOPATH environment variable lists places to look for Go code.
+On Unix, the value is a colon-separated string.
+On Windows, the value is a semicolon-separated string.
+On Plan 9, the value is a list.
+
+GOPATH must be set to get, build and install packages outside the
+standard Go tree.
+
+Each directory listed in GOPATH must have a prescribed structure:
+
+The src/ directory holds source code.  The path below 'src'
+determines the import path or executable name.
+
+The pkg/ directory holds installed package objects.
+As in the Go tree, each target operating system and
+architecture pair has its own subdirectory of pkg
+(pkg/GOOS_GOARCH).
+
+If DIR is a directory listed in the GOPATH, a package with
+source in DIR/src/foo/bar can be imported as "foo/bar" and
+has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a".
+
+The bin/ directory holds compiled commands.
+Each command is named for its source directory, but only
+the final element, not the entire path.  That is, the
+command with source in DIR/src/foo/quux is installed into
+DIR/bin/quux, not DIR/bin/foo/quux.  The foo/ is stripped
+so that you can add DIR/bin to your PATH to get at the
+installed commands.  If the GOBIN environment variable is
+set, commands are installed to the directory it names instead
+of DIR/bin.
+
+Here's an example directory layout:
+
+    GOPATH=/home/user/gocode
+
+    /home/user/gocode/
+        src/
+            foo/
+                bar/               (go code in package bar)
+                    x.go
+                quux/              (go code in package main)
+                    y.go
+        bin/
+            quux                   (installed command)
+        pkg/
+            linux_amd64/
+                foo/
+                    bar.a          (installed package object)
+
+Go searches each directory listed in GOPATH to find source code,
+but new packages are always downloaded into the first directory
+in the list.
+	`,
+}
+
+var helpFileType = &Command{
+	UsageLine: "filetype",
+	Short:     "file types",
+	Long: `
+The go command examines the contents of a restricted set of files
+in each directory. It identifies which files to examine based on
+the extension of the file name. These extensions are:
+
+	.go
+		Go source files.
+	.c, .h
+		C source files.
+		If the package uses cgo, these will be compiled with the
+		OS-native compiler (typically gcc); otherwise they will be
+		compiled with the Go-specific support compiler,
+		5c, 6c, or 8c, etc. as appropriate.
+	.cc, .cpp, .cxx, .hh, .hpp, .hxx
+		C++ source files. Only useful with cgo or SWIG, and always
+		compiled with the OS-native compiler.
+	.m
+		Objective-C source files. Only useful with cgo, and always
+		compiled with the OS-native compiler.
+	.s, .S
+		Assembler source files.
+		If the package uses cgo, these will be assembled with the
+		OS-native assembler (typically gcc (sic)); otherwise they
+		will be assembled with the Go-specific support assembler,
+		5a, 6a, or 8a, etc., as appropriate.
+	.swig, .swigcxx
+		SWIG definition files.
+	.syso
+		System object files.
+
+Files of each of these types except .syso may contain build
+constraints, but the go command stops scanning for build constraints
+at the first item in the file that is not a blank line or //-style
+line comment.
+	`,
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/http.go b/third_party/gofrontend/libgo/go/cmd/go/http.go
new file mode 100644
index 0000000..107b820
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/http.go
@@ -0,0 +1,87 @@
+// 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.
+
+// +build !cmd_go_bootstrap
+
+// This code is compiled into the real 'go' binary, but it is not
+// compiled into the binary that is built during all.bash, so as
+// to avoid needing to build net (and thus use cgo) during the
+// bootstrap process.
+
+package main
+
+import (
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"net/http"
+	"net/url"
+)
+
+// httpClient is the default HTTP client, but a variable so it can be
+// changed by tests, without modifying http.DefaultClient.
+var httpClient = http.DefaultClient
+
+// httpGET returns the data from an HTTP GET request for the given URL.
+func httpGET(url string) ([]byte, error) {
+	resp, err := httpClient.Get(url)
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Body.Close()
+	if resp.StatusCode != 200 {
+		return nil, fmt.Errorf("%s: %s", url, resp.Status)
+	}
+	b, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return nil, fmt.Errorf("%s: %v", url, err)
+	}
+	return b, nil
+}
+
+// httpsOrHTTP returns the body of either the importPath's
+// https resource or, if unavailable, the http resource.
+func httpsOrHTTP(importPath string) (urlStr string, body io.ReadCloser, err error) {
+	fetch := func(scheme string) (urlStr string, res *http.Response, err error) {
+		u, err := url.Parse(scheme + "://" + importPath)
+		if err != nil {
+			return "", nil, err
+		}
+		u.RawQuery = "go-get=1"
+		urlStr = u.String()
+		if buildV {
+			log.Printf("Fetching %s", urlStr)
+		}
+		res, err = httpClient.Get(urlStr)
+		return
+	}
+	closeBody := func(res *http.Response) {
+		if res != nil {
+			res.Body.Close()
+		}
+	}
+	urlStr, res, err := fetch("https")
+	if err != nil || res.StatusCode != 200 {
+		if buildV {
+			if err != nil {
+				log.Printf("https fetch failed.")
+			} else {
+				log.Printf("ignoring https fetch with status code %d", res.StatusCode)
+			}
+		}
+		closeBody(res)
+		urlStr, res, err = fetch("http")
+	}
+	if err != nil {
+		closeBody(res)
+		return "", nil, err
+	}
+	// Note: accepting a non-200 OK here, so people can serve a
+	// meta import in their http 404 page.
+	if buildV {
+		log.Printf("Parsing meta tags from %s (status code %d)", urlStr, res.StatusCode)
+	}
+	return urlStr, res.Body, nil
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/list.go b/third_party/gofrontend/libgo/go/cmd/go/list.go
new file mode 100644
index 0000000..0ead435
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/list.go
@@ -0,0 +1,208 @@
+// Copyright 2011 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 (
+	"bufio"
+	"encoding/json"
+	"io"
+	"os"
+	"strings"
+	"text/template"
+)
+
+var cmdList = &Command{
+	UsageLine: "list [-e] [-f format] [-json] [build flags] [packages]",
+	Short:     "list packages",
+	Long: `
+List lists the packages named by the import paths, one per line.
+
+The default output shows the package import path:
+
+    code.google.com/p/google-api-go-client/books/v1
+    code.google.com/p/goauth2/oauth
+    code.google.com/p/sqlite
+
+The -f flag specifies an alternate format for the list, using the
+syntax of package template.  The default output is equivalent to -f
+'{{.ImportPath}}'. The struct being passed to the template is:
+
+    type Package struct {
+        Dir        string // directory containing package sources
+        ImportPath string // import path of package in dir
+        Name       string // package name
+        Doc        string // package documentation string
+        Target     string // install path
+        Goroot     bool   // is this package in the Go root?
+        Standard   bool   // is this package part of the standard Go library?
+        Stale      bool   // would 'go install' do anything for this package?
+        Root       string // Go root or Go path dir containing this package
+
+        // Source files
+        GoFiles  []string       // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
+        CgoFiles []string       // .go sources files that import "C"
+        IgnoredGoFiles []string // .go sources ignored due to build constraints
+        CFiles   []string       // .c source files
+        CXXFiles []string       // .cc, .cxx and .cpp source files
+        MFiles   []string       // .m source files
+        HFiles   []string       // .h, .hh, .hpp and .hxx source files
+        SFiles   []string       // .s source files
+        SwigFiles []string      // .swig files
+        SwigCXXFiles []string   // .swigcxx files
+        SysoFiles []string      // .syso object files to add to archive
+
+        // Cgo directives
+        CgoCFLAGS    []string // cgo: flags for C compiler
+        CgoCPPFLAGS  []string // cgo: flags for C preprocessor
+        CgoCXXFLAGS  []string // cgo: flags for C++ compiler
+        CgoLDFLAGS   []string // cgo: flags for linker
+        CgoPkgConfig []string // cgo: pkg-config names
+
+        // Dependency information
+        Imports []string // import paths used by this package
+        Deps    []string // all (recursively) imported dependencies
+
+        // Error information
+        Incomplete bool            // this package or a dependency has an error
+        Error      *PackageError   // error loading package
+        DepsErrors []*PackageError // errors loading dependencies
+
+        TestGoFiles  []string // _test.go files in package
+        TestImports  []string // imports from TestGoFiles
+        XTestGoFiles []string // _test.go files outside package
+        XTestImports []string // imports from XTestGoFiles
+    }
+
+The template function "join" calls strings.Join.
+
+The template function "context" returns the build context, defined as:
+
+	type Context struct {
+		GOARCH        string   // target architecture
+		GOOS          string   // target operating system
+		GOROOT        string   // Go root
+		GOPATH        string   // Go path
+		CgoEnabled    bool     // whether cgo can be used
+		UseAllFiles   bool     // use files regardless of +build lines, file names
+		Compiler      string   // compiler to assume when computing target paths
+		BuildTags     []string // build constraints to match in +build lines
+		ReleaseTags   []string // releases the current release is compatible with
+		InstallSuffix string   // suffix to use in the name of the install dir
+	}
+
+For more information about the meaning of these fields see the documentation
+for the go/build package's Context type.
+
+The -json flag causes the package data to be printed in JSON format
+instead of using the template format.
+
+The -e flag changes the handling of erroneous packages, those that
+cannot be found or are malformed.  By default, the list command
+prints an error to standard error for each erroneous package and
+omits the packages from consideration during the usual printing.
+With the -e flag, the list command never prints errors to standard
+error and instead processes the erroneous packages with the usual
+printing.  Erroneous packages will have a non-empty ImportPath and
+a non-nil Error field; other information may or may not be missing
+(zeroed).
+
+For more about build flags, see 'go help build'.
+
+For more about specifying packages, see 'go help packages'.
+	`,
+}
+
+func init() {
+	cmdList.Run = runList // break init cycle
+	addBuildFlags(cmdList)
+}
+
+var listE = cmdList.Flag.Bool("e", false, "")
+var listFmt = cmdList.Flag.String("f", "{{.ImportPath}}", "")
+var listJson = cmdList.Flag.Bool("json", false, "")
+var nl = []byte{'\n'}
+
+func runList(cmd *Command, args []string) {
+	out := newTrackingWriter(os.Stdout)
+	defer out.w.Flush()
+
+	var do func(*Package)
+	if *listJson {
+		do = func(p *Package) {
+			b, err := json.MarshalIndent(p, "", "\t")
+			if err != nil {
+				out.Flush()
+				fatalf("%s", err)
+			}
+			out.Write(b)
+			out.Write(nl)
+		}
+	} else {
+		var cachedCtxt *Context
+		context := func() *Context {
+			if cachedCtxt == nil {
+				cachedCtxt = newContext(&buildContext)
+			}
+			return cachedCtxt
+		}
+		fm := template.FuncMap{
+			"join":    strings.Join,
+			"context": context,
+		}
+		tmpl, err := template.New("main").Funcs(fm).Parse(*listFmt)
+		if err != nil {
+			fatalf("%s", err)
+		}
+		do = func(p *Package) {
+			if err := tmpl.Execute(out, p); err != nil {
+				out.Flush()
+				fatalf("%s", err)
+			}
+			if out.NeedNL() {
+				out.Write(nl)
+			}
+		}
+	}
+
+	load := packages
+	if *listE {
+		load = packagesAndErrors
+	}
+
+	for _, pkg := range load(args) {
+		do(pkg)
+	}
+}
+
+// TrackingWriter tracks the last byte written on every write so
+// we can avoid printing a newline if one was already written or
+// if there is no output at all.
+type TrackingWriter struct {
+	w    *bufio.Writer
+	last byte
+}
+
+func newTrackingWriter(w io.Writer) *TrackingWriter {
+	return &TrackingWriter{
+		w:    bufio.NewWriter(w),
+		last: '\n',
+	}
+}
+
+func (t *TrackingWriter) Write(p []byte) (n int, err error) {
+	n, err = t.w.Write(p)
+	if n > 0 {
+		t.last = p[n-1]
+	}
+	return
+}
+
+func (t *TrackingWriter) Flush() {
+	t.w.Flush()
+}
+
+func (t *TrackingWriter) NeedNL() bool {
+	return t.last != '\n'
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/main.go b/third_party/gofrontend/libgo/go/cmd/go/main.go
new file mode 100644
index 0000000..5b1194a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/main.go
@@ -0,0 +1,722 @@
+// Copyright 2011 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 (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/build"
+	"io"
+	"log"
+	"os"
+	"os/exec"
+	"path"
+	"path/filepath"
+	"regexp"
+	"runtime"
+	"strings"
+	"sync"
+	"text/template"
+	"unicode"
+	"unicode/utf8"
+)
+
+// A Command is an implementation of a go command
+// like go build or go fix.
+type Command struct {
+	// Run runs the command.
+	// The args are the arguments after the command name.
+	Run func(cmd *Command, args []string)
+
+	// UsageLine is the one-line usage message.
+	// The first word in the line is taken to be the command name.
+	UsageLine string
+
+	// Short is the short description shown in the 'go help' output.
+	Short string
+
+	// Long is the long message shown in the 'go help <this-command>' output.
+	Long string
+
+	// Flag is a set of flags specific to this command.
+	Flag flag.FlagSet
+
+	// CustomFlags indicates that the command will do its own
+	// flag parsing.
+	CustomFlags bool
+}
+
+// Name returns the command's name: the first word in the usage line.
+func (c *Command) Name() string {
+	name := c.UsageLine
+	i := strings.Index(name, " ")
+	if i >= 0 {
+		name = name[:i]
+	}
+	return name
+}
+
+func (c *Command) Usage() {
+	fmt.Fprintf(os.Stderr, "usage: %s\n\n", c.UsageLine)
+	fmt.Fprintf(os.Stderr, "%s\n", strings.TrimSpace(c.Long))
+	os.Exit(2)
+}
+
+// Runnable reports whether the command can be run; otherwise
+// it is a documentation pseudo-command such as importpath.
+func (c *Command) Runnable() bool {
+	return c.Run != nil
+}
+
+// Commands lists the available commands and help topics.
+// The order here is the order in which they are printed by 'go help'.
+var commands = []*Command{
+	cmdBuild,
+	cmdClean,
+	cmdEnv,
+	cmdFix,
+	cmdFmt,
+	cmdGet,
+	cmdInstall,
+	cmdList,
+	cmdRun,
+	cmdTest,
+	cmdTool,
+	cmdVersion,
+	cmdVet,
+
+	helpC,
+	helpFileType,
+	helpGopath,
+	helpImportPath,
+	helpPackages,
+	helpTestflag,
+	helpTestfunc,
+}
+
+var exitStatus = 0
+var exitMu sync.Mutex
+
+func setExitStatus(n int) {
+	exitMu.Lock()
+	if exitStatus < n {
+		exitStatus = n
+	}
+	exitMu.Unlock()
+}
+
+func main() {
+	_ = go11tag
+	flag.Usage = usage
+	flag.Parse()
+	log.SetFlags(0)
+
+	args := flag.Args()
+	if len(args) < 1 {
+		usage()
+	}
+
+	if args[0] == "help" {
+		help(args[1:])
+		return
+	}
+
+	// Diagnose common mistake: GOPATH==GOROOT.
+	// This setting is equivalent to not setting GOPATH at all,
+	// which is not what most people want when they do it.
+	if gopath := os.Getenv("GOPATH"); gopath == runtime.GOROOT() {
+		fmt.Fprintf(os.Stderr, "warning: GOPATH set to GOROOT (%s) has no effect\n", gopath)
+	} else {
+		for _, p := range filepath.SplitList(gopath) {
+			// Note: using HasPrefix instead of Contains because a ~ can appear
+			// in the middle of directory elements, such as /tmp/git-1.8.2~rc3
+			// or C:\PROGRA~1. Only ~ as a path prefix has meaning to the shell.
+			if strings.HasPrefix(p, "~") {
+				fmt.Fprintf(os.Stderr, "go: GOPATH entry cannot start with shell metacharacter '~': %q\n", p)
+				os.Exit(2)
+			}
+			if build.IsLocalImport(p) {
+				fmt.Fprintf(os.Stderr, "go: GOPATH entry is relative; must be absolute path: %q.\nRun 'go help gopath' for usage.\n", p)
+				os.Exit(2)
+			}
+		}
+	}
+
+	if fi, err := os.Stat(goroot); err != nil || !fi.IsDir() {
+		fmt.Fprintf(os.Stderr, "go: cannot find GOROOT directory: %v\n", goroot)
+		os.Exit(2)
+	}
+
+	for _, cmd := range commands {
+		if cmd.Name() == args[0] && cmd.Run != nil {
+			cmd.Flag.Usage = func() { cmd.Usage() }
+			if cmd.CustomFlags {
+				args = args[1:]
+			} else {
+				cmd.Flag.Parse(args[1:])
+				args = cmd.Flag.Args()
+			}
+			cmd.Run(cmd, args)
+			exit()
+			return
+		}
+	}
+
+	fmt.Fprintf(os.Stderr, "go: unknown subcommand %q\nRun 'go help' for usage.\n", args[0])
+	setExitStatus(2)
+	exit()
+}
+
+var usageTemplate = `Go is a tool for managing Go source code.
+
+Usage:
+
+	go command [arguments]
+
+The commands are:
+{{range .}}{{if .Runnable}}
+    {{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
+
+Use "go help [command]" for more information about a command.
+
+Additional help topics:
+{{range .}}{{if not .Runnable}}
+    {{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
+
+Use "go help [topic]" for more information about that topic.
+
+`
+
+var helpTemplate = `{{if .Runnable}}usage: go {{.UsageLine}}
+
+{{end}}{{.Long | trim}}
+`
+
+var documentationTemplate = `// Copyright 2011 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.
+
+// DO NOT EDIT THIS FILE. GENERATED BY mkdoc.sh.
+// Edit the documentation in other files and rerun mkdoc.sh to generate this one.
+
+/*
+{{range .}}{{if .Short}}{{.Short | capitalize}}
+
+{{end}}{{if .Runnable}}Usage:
+
+	go {{.UsageLine}}
+
+{{end}}{{.Long | trim}}
+
+
+{{end}}*/
+package main
+`
+
+// tmpl executes the given template text on data, writing the result to w.
+func tmpl(w io.Writer, text string, data interface{}) {
+	t := template.New("top")
+	t.Funcs(template.FuncMap{"trim": strings.TrimSpace, "capitalize": capitalize})
+	template.Must(t.Parse(text))
+	if err := t.Execute(w, data); err != nil {
+		panic(err)
+	}
+}
+
+func capitalize(s string) string {
+	if s == "" {
+		return s
+	}
+	r, n := utf8.DecodeRuneInString(s)
+	return string(unicode.ToTitle(r)) + s[n:]
+}
+
+func printUsage(w io.Writer) {
+	tmpl(w, usageTemplate, commands)
+}
+
+func usage() {
+	// special case "go test -h"
+	if len(os.Args) > 1 && os.Args[1] == "test" {
+		help([]string{"testflag"})
+		os.Exit(2)
+	}
+	printUsage(os.Stderr)
+	os.Exit(2)
+}
+
+// help implements the 'help' command.
+func help(args []string) {
+	if len(args) == 0 {
+		printUsage(os.Stdout)
+		// not exit 2: succeeded at 'go help'.
+		return
+	}
+	if len(args) != 1 {
+		fmt.Fprintf(os.Stderr, "usage: go help command\n\nToo many arguments given.\n")
+		os.Exit(2) // failed at 'go help'
+	}
+
+	arg := args[0]
+
+	// 'go help documentation' generates doc.go.
+	if arg == "documentation" {
+		buf := new(bytes.Buffer)
+		printUsage(buf)
+		usage := &Command{Long: buf.String()}
+		tmpl(os.Stdout, documentationTemplate, append([]*Command{usage}, commands...))
+		return
+	}
+
+	for _, cmd := range commands {
+		if cmd.Name() == arg {
+			tmpl(os.Stdout, helpTemplate, cmd)
+			// not exit 2: succeeded at 'go help cmd'.
+			return
+		}
+	}
+
+	fmt.Fprintf(os.Stderr, "Unknown help topic %#q.  Run 'go help'.\n", arg)
+	os.Exit(2) // failed at 'go help cmd'
+}
+
+// importPathsNoDotExpansion returns the import paths to use for the given
+// command line, but it does no ... expansion.
+func importPathsNoDotExpansion(args []string) []string {
+	if len(args) == 0 {
+		return []string{"."}
+	}
+	var out []string
+	for _, a := range args {
+		// Arguments are supposed to be import paths, but
+		// as a courtesy to Windows developers, rewrite \ to /
+		// in command-line arguments.  Handles .\... and so on.
+		if filepath.Separator == '\\' {
+			a = strings.Replace(a, `\`, `/`, -1)
+		}
+
+		// Put argument in canonical form, but preserve leading ./.
+		if strings.HasPrefix(a, "./") {
+			a = "./" + path.Clean(a)
+			if a == "./." {
+				a = "."
+			}
+		} else {
+			a = path.Clean(a)
+		}
+		if a == "all" || a == "std" {
+			out = append(out, allPackages(a)...)
+			continue
+		}
+		out = append(out, a)
+	}
+	return out
+}
+
+// importPaths returns the import paths to use for the given command line.
+func importPaths(args []string) []string {
+	args = importPathsNoDotExpansion(args)
+	var out []string
+	for _, a := range args {
+		if strings.Contains(a, "...") {
+			if build.IsLocalImport(a) {
+				out = append(out, allPackagesInFS(a)...)
+			} else {
+				out = append(out, allPackages(a)...)
+			}
+			continue
+		}
+		out = append(out, a)
+	}
+	return out
+}
+
+var atexitFuncs []func()
+
+func atexit(f func()) {
+	atexitFuncs = append(atexitFuncs, f)
+}
+
+func exit() {
+	for _, f := range atexitFuncs {
+		f()
+	}
+	os.Exit(exitStatus)
+}
+
+func fatalf(format string, args ...interface{}) {
+	errorf(format, args...)
+	exit()
+}
+
+func errorf(format string, args ...interface{}) {
+	log.Printf(format, args...)
+	setExitStatus(1)
+}
+
+var logf = log.Printf
+
+func exitIfErrors() {
+	if exitStatus != 0 {
+		exit()
+	}
+}
+
+func run(cmdargs ...interface{}) {
+	cmdline := stringList(cmdargs...)
+	if buildN || buildX {
+		fmt.Printf("%s\n", strings.Join(cmdline, " "))
+		if buildN {
+			return
+		}
+	}
+
+	cmd := exec.Command(cmdline[0], cmdline[1:]...)
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	if err := cmd.Run(); err != nil {
+		errorf("%v", err)
+	}
+}
+
+func runOut(dir string, cmdargs ...interface{}) []byte {
+	cmdline := stringList(cmdargs...)
+	cmd := exec.Command(cmdline[0], cmdline[1:]...)
+	cmd.Dir = dir
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		os.Stderr.Write(out)
+		errorf("%v", err)
+		out = nil
+	}
+	return out
+}
+
+// envForDir returns a copy of the environment
+// suitable for running in the given directory.
+// The environment is the current process's environment
+// but with an updated $PWD, so that an os.Getwd in the
+// child will be faster.
+func envForDir(dir string) []string {
+	env := os.Environ()
+	// Internally we only use rooted paths, so dir is rooted.
+	// Even if dir is not rooted, no harm done.
+	return mergeEnvLists([]string{"PWD=" + dir}, env)
+}
+
+// mergeEnvLists merges the two environment lists such that
+// variables with the same name in "in" replace those in "out".
+func mergeEnvLists(in, out []string) []string {
+NextVar:
+	for _, inkv := range in {
+		k := strings.SplitAfterN(inkv, "=", 2)[0]
+		for i, outkv := range out {
+			if strings.HasPrefix(outkv, k) {
+				out[i] = inkv
+				continue NextVar
+			}
+		}
+		out = append(out, inkv)
+	}
+	return out
+}
+
+// matchPattern(pattern)(name) reports whether
+// name matches pattern.  Pattern is a limited glob
+// pattern in which '...' means 'any string' and there
+// is no other special syntax.
+func matchPattern(pattern string) func(name string) bool {
+	re := regexp.QuoteMeta(pattern)
+	re = strings.Replace(re, `\.\.\.`, `.*`, -1)
+	// Special case: foo/... matches foo too.
+	if strings.HasSuffix(re, `/.*`) {
+		re = re[:len(re)-len(`/.*`)] + `(/.*)?`
+	}
+	reg := regexp.MustCompile(`^` + re + `$`)
+	return func(name string) bool {
+		return reg.MatchString(name)
+	}
+}
+
+// hasPathPrefix reports whether the path s begins with the
+// elements in prefix.
+func hasPathPrefix(s, prefix string) bool {
+	switch {
+	default:
+		return false
+	case len(s) == len(prefix):
+		return s == prefix
+	case len(s) > len(prefix):
+		if prefix != "" && prefix[len(prefix)-1] == '/' {
+			return strings.HasPrefix(s, prefix)
+		}
+		return s[len(prefix)] == '/' && s[:len(prefix)] == prefix
+	}
+}
+
+// treeCanMatchPattern(pattern)(name) reports whether
+// name or children of name can possibly match pattern.
+// Pattern is the same limited glob accepted by matchPattern.
+func treeCanMatchPattern(pattern string) func(name string) bool {
+	wildCard := false
+	if i := strings.Index(pattern, "..."); i >= 0 {
+		wildCard = true
+		pattern = pattern[:i]
+	}
+	return func(name string) bool {
+		return len(name) <= len(pattern) && hasPathPrefix(pattern, name) ||
+			wildCard && strings.HasPrefix(name, pattern)
+	}
+}
+
+// allPackages returns all the packages that can be found
+// under the $GOPATH directories and $GOROOT matching pattern.
+// The pattern is either "all" (all packages), "std" (standard packages)
+// or a path including "...".
+func allPackages(pattern string) []string {
+	pkgs := matchPackages(pattern)
+	if len(pkgs) == 0 {
+		fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
+	}
+	return pkgs
+}
+
+func matchPackages(pattern string) []string {
+	match := func(string) bool { return true }
+	treeCanMatch := func(string) bool { return true }
+	if pattern != "all" && pattern != "std" {
+		match = matchPattern(pattern)
+		treeCanMatch = treeCanMatchPattern(pattern)
+	}
+
+	have := map[string]bool{
+		"builtin": true, // ignore pseudo-package that exists only for documentation
+	}
+	if !buildContext.CgoEnabled {
+		have["runtime/cgo"] = true // ignore during walk
+	}
+	var pkgs []string
+
+	// Commands
+	cmd := filepath.Join(goroot, "src/cmd") + string(filepath.Separator)
+	filepath.Walk(cmd, func(path string, fi os.FileInfo, err error) error {
+		if err != nil || !fi.IsDir() || path == cmd {
+			return nil
+		}
+		name := path[len(cmd):]
+		if !treeCanMatch(name) {
+			return filepath.SkipDir
+		}
+		// Commands are all in cmd/, not in subdirectories.
+		if strings.Contains(name, string(filepath.Separator)) {
+			return filepath.SkipDir
+		}
+
+		// We use, e.g., cmd/gofmt as the pseudo import path for gofmt.
+		name = "cmd/" + name
+		if have[name] {
+			return nil
+		}
+		have[name] = true
+		if !match(name) {
+			return nil
+		}
+		_, err = buildContext.ImportDir(path, 0)
+		if err != nil {
+			if _, noGo := err.(*build.NoGoError); !noGo {
+				log.Print(err)
+			}
+			return nil
+		}
+		pkgs = append(pkgs, name)
+		return nil
+	})
+
+	for _, src := range buildContext.SrcDirs() {
+		if pattern == "std" && src != gorootSrcPkg {
+			continue
+		}
+		src = filepath.Clean(src) + string(filepath.Separator)
+		filepath.Walk(src, func(path string, fi os.FileInfo, err error) error {
+			if err != nil || !fi.IsDir() || path == src {
+				return nil
+			}
+
+			// Avoid .foo, _foo, and testdata directory trees.
+			_, elem := filepath.Split(path)
+			if strings.HasPrefix(elem, ".") || strings.HasPrefix(elem, "_") || elem == "testdata" {
+				return filepath.SkipDir
+			}
+
+			name := filepath.ToSlash(path[len(src):])
+			if pattern == "std" && strings.Contains(name, ".") {
+				return filepath.SkipDir
+			}
+			if !treeCanMatch(name) {
+				return filepath.SkipDir
+			}
+			if have[name] {
+				return nil
+			}
+			have[name] = true
+			if !match(name) {
+				return nil
+			}
+			_, err = buildContext.ImportDir(path, 0)
+			if err != nil {
+				if _, noGo := err.(*build.NoGoError); noGo {
+					return nil
+				}
+			}
+			pkgs = append(pkgs, name)
+			return nil
+		})
+	}
+	return pkgs
+}
+
+// allPackagesInFS is like allPackages but is passed a pattern
+// beginning ./ or ../, meaning it should scan the tree rooted
+// at the given directory.  There are ... in the pattern too.
+func allPackagesInFS(pattern string) []string {
+	pkgs := matchPackagesInFS(pattern)
+	if len(pkgs) == 0 {
+		fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
+	}
+	return pkgs
+}
+
+func matchPackagesInFS(pattern string) []string {
+	// Find directory to begin the scan.
+	// Could be smarter but this one optimization
+	// is enough for now, since ... is usually at the
+	// end of a path.
+	i := strings.Index(pattern, "...")
+	dir, _ := path.Split(pattern[:i])
+
+	// pattern begins with ./ or ../.
+	// path.Clean will discard the ./ but not the ../.
+	// We need to preserve the ./ for pattern matching
+	// and in the returned import paths.
+	prefix := ""
+	if strings.HasPrefix(pattern, "./") {
+		prefix = "./"
+	}
+	match := matchPattern(pattern)
+
+	var pkgs []string
+	filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error {
+		if err != nil || !fi.IsDir() {
+			return nil
+		}
+		if path == dir {
+			// filepath.Walk starts at dir and recurses. For the recursive case,
+			// the path is the result of filepath.Join, which calls filepath.Clean.
+			// The initial case is not Cleaned, though, so we do this explicitly.
+			//
+			// This converts a path like "./io/" to "io". Without this step, running
+			// "cd $GOROOT/src/pkg; go list ./io/..." would incorrectly skip the io
+			// package, because prepending the prefix "./" to the unclean path would
+			// result in "././io", and match("././io") returns false.
+			path = filepath.Clean(path)
+		}
+
+		// Avoid .foo, _foo, and testdata directory trees, but do not avoid "." or "..".
+		_, elem := filepath.Split(path)
+		dot := strings.HasPrefix(elem, ".") && elem != "." && elem != ".."
+		if dot || strings.HasPrefix(elem, "_") || elem == "testdata" {
+			return filepath.SkipDir
+		}
+
+		name := prefix + filepath.ToSlash(path)
+		if !match(name) {
+			return nil
+		}
+		if _, err = build.ImportDir(path, 0); err != nil {
+			if _, noGo := err.(*build.NoGoError); !noGo {
+				log.Print(err)
+			}
+			return nil
+		}
+		pkgs = append(pkgs, name)
+		return nil
+	})
+	return pkgs
+}
+
+// stringList's arguments should be a sequence of string or []string values.
+// stringList flattens them into a single []string.
+func stringList(args ...interface{}) []string {
+	var x []string
+	for _, arg := range args {
+		switch arg := arg.(type) {
+		case []string:
+			x = append(x, arg...)
+		case string:
+			x = append(x, arg)
+		default:
+			panic("stringList: invalid argument")
+		}
+	}
+	return x
+}
+
+// toFold returns a string with the property that
+//	strings.EqualFold(s, t) iff toFold(s) == toFold(t)
+// This lets us test a large set of strings for fold-equivalent
+// duplicates without making a quadratic number of calls
+// to EqualFold. Note that strings.ToUpper and strings.ToLower
+// have the desired property in some corner cases.
+func toFold(s string) string {
+	// Fast path: all ASCII, no upper case.
+	// Most paths look like this already.
+	for i := 0; i < len(s); i++ {
+		c := s[i]
+		if c >= utf8.RuneSelf || 'A' <= c && c <= 'Z' {
+			goto Slow
+		}
+	}
+	return s
+
+Slow:
+	var buf bytes.Buffer
+	for _, r := range s {
+		// SimpleFold(x) cycles to the next equivalent rune > x
+		// or wraps around to smaller values. Iterate until it wraps,
+		// and we've found the minimum value.
+		for {
+			r0 := r
+			r = unicode.SimpleFold(r0)
+			if r <= r0 {
+				break
+			}
+		}
+		// Exception to allow fast path above: A-Z => a-z
+		if 'A' <= r && r <= 'Z' {
+			r += 'a' - 'A'
+		}
+		buf.WriteRune(r)
+	}
+	return buf.String()
+}
+
+// foldDup reports a pair of strings from the list that are
+// equal according to strings.EqualFold.
+// It returns "", "" if there are no such strings.
+func foldDup(list []string) (string, string) {
+	clash := map[string]string{}
+	for _, s := range list {
+		fold := toFold(s)
+		if t := clash[fold]; t != "" {
+			if s > t {
+				s, t = t, s
+			}
+			return s, t
+		}
+		clash[fold] = s
+	}
+	return "", ""
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/match_test.go b/third_party/gofrontend/libgo/go/cmd/go/match_test.go
new file mode 100644
index 0000000..38b9b11
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/match_test.go
@@ -0,0 +1,88 @@
+// 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 main
+
+import "testing"
+
+var matchPatternTests = []stringPairTest{
+	{"...", "foo", true},
+	{"net", "net", true},
+	{"net", "net/http", false},
+	{"net/http", "net", false},
+	{"net/http", "net/http", true},
+	{"net...", "netchan", true},
+	{"net...", "net", true},
+	{"net...", "net/http", true},
+	{"net...", "not/http", false},
+	{"net/...", "netchan", false},
+	{"net/...", "net", true},
+	{"net/...", "net/http", true},
+	{"net/...", "not/http", false},
+}
+
+func TestMatchPattern(t *testing.T) {
+	testStringPairs(t, "matchPattern", matchPatternTests, func(pattern, name string) bool {
+		return matchPattern(pattern)(name)
+	})
+}
+
+var treeCanMatchPatternTests = []stringPairTest{
+	{"...", "foo", true},
+	{"net", "net", true},
+	{"net", "net/http", false},
+	{"net/http", "net", true},
+	{"net/http", "net/http", true},
+	{"net...", "netchan", true},
+	{"net...", "net", true},
+	{"net...", "net/http", true},
+	{"net...", "not/http", false},
+	{"net/...", "netchan", false},
+	{"net/...", "net", true},
+	{"net/...", "net/http", true},
+	{"net/...", "not/http", false},
+	{"abc.../def", "abcxyz", true},
+	{"abc.../def", "xyxabc", false},
+	{"x/y/z/...", "x", true},
+	{"x/y/z/...", "x/y", true},
+	{"x/y/z/...", "x/y/z", true},
+	{"x/y/z/...", "x/y/z/w", true},
+	{"x/y/z", "x", true},
+	{"x/y/z", "x/y", true},
+	{"x/y/z", "x/y/z", true},
+	{"x/y/z", "x/y/z/w", false},
+	{"x/.../y/z", "x/a/b/c", true},
+	{"x/.../y/z", "y/x/a/b/c", false},
+}
+
+func TestChildrenCanMatchPattern(t *testing.T) {
+	testStringPairs(t, "treeCanMatchPattern", treeCanMatchPatternTests, func(pattern, name string) bool {
+		return treeCanMatchPattern(pattern)(name)
+	})
+}
+
+var hasPathPrefixTests = []stringPairTest{
+	{"abc", "a", false},
+	{"a/bc", "a", true},
+	{"a", "a", true},
+	{"a/bc", "a/", true},
+}
+
+func TestHasPathPrefix(t *testing.T) {
+	testStringPairs(t, "hasPathPrefix", hasPathPrefixTests, hasPathPrefix)
+}
+
+type stringPairTest struct {
+	in1 string
+	in2 string
+	out bool
+}
+
+func testStringPairs(t *testing.T, name string, tests []stringPairTest, f func(string, string) bool) {
+	for _, tt := range tests {
+		if out := f(tt.in1, tt.in2); out != tt.out {
+			t.Errorf("%s(%q, %q) = %v, want %v", name, tt.in1, tt.in2, out, tt.out)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/mkdoc.sh b/third_party/gofrontend/libgo/go/cmd/go/mkdoc.sh
new file mode 100755
index 0000000..12fd7ba
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/mkdoc.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+# 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.
+
+go install # So the next line will produce updated documentation.
+go help documentation > doc.go
+gofmt -w doc.go
+
diff --git a/third_party/gofrontend/libgo/go/cmd/go/pkg.go b/third_party/gofrontend/libgo/go/cmd/go/pkg.go
new file mode 100644
index 0000000..b700ad5
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/pkg.go
@@ -0,0 +1,856 @@
+// Copyright 2011 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 (
+	"bytes"
+	"errors"
+	"fmt"
+	"go/build"
+	"go/scanner"
+	"go/token"
+	"os"
+	pathpkg "path"
+	"path/filepath"
+	"sort"
+	"strings"
+	"time"
+	"unicode"
+)
+
+// A Package describes a single package found in a directory.
+type Package struct {
+	// Note: These fields are part of the go command's public API.
+	// See list.go.  It is okay to add fields, but not to change or
+	// remove existing ones.  Keep in sync with list.go
+	Dir         string `json:",omitempty"` // directory containing package sources
+	ImportPath  string `json:",omitempty"` // import path of package in dir
+	Name        string `json:",omitempty"` // package name
+	Doc         string `json:",omitempty"` // package documentation string
+	Target      string `json:",omitempty"` // install path
+	Goroot      bool   `json:",omitempty"` // is this package found in the Go root?
+	Standard    bool   `json:",omitempty"` // is this package part of the standard Go library?
+	Stale       bool   `json:",omitempty"` // would 'go install' do anything for this package?
+	Root        string `json:",omitempty"` // Go root or Go path dir containing this package
+	ConflictDir string `json:",omitempty"` // Dir is hidden by this other directory
+
+	// Source files
+	GoFiles        []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
+	CgoFiles       []string `json:",omitempty"` // .go sources files that import "C"
+	IgnoredGoFiles []string `json:",omitempty"` // .go sources ignored due to build constraints
+	CFiles         []string `json:",omitempty"` // .c source files
+	CXXFiles       []string `json:",omitempty"` // .cc, .cpp and .cxx source files
+	MFiles         []string `json:",omitempty"` // .m source files
+	HFiles         []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files
+	SFiles         []string `json:",omitempty"` // .s source files
+	SwigFiles      []string `json:",omitempty"` // .swig files
+	SwigCXXFiles   []string `json:",omitempty"` // .swigcxx files
+	SysoFiles      []string `json:",omitempty"` // .syso system object files added to package
+
+	// Cgo directives
+	CgoCFLAGS    []string `json:",omitempty"` // cgo: flags for C compiler
+	CgoCPPFLAGS  []string `json:",omitempty"` // cgo: flags for C preprocessor
+	CgoCXXFLAGS  []string `json:",omitempty"` // cgo: flags for C++ compiler
+	CgoLDFLAGS   []string `json:",omitempty"` // cgo: flags for linker
+	CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names
+
+	// Dependency information
+	Imports []string `json:",omitempty"` // import paths used by this package
+	Deps    []string `json:",omitempty"` // all (recursively) imported dependencies
+
+	// Error information
+	Incomplete bool            `json:",omitempty"` // was there an error loading this package or dependencies?
+	Error      *PackageError   `json:",omitempty"` // error loading this package (not dependencies)
+	DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies
+
+	// Test information
+	TestGoFiles  []string `json:",omitempty"` // _test.go files in package
+	TestImports  []string `json:",omitempty"` // imports from TestGoFiles
+	XTestGoFiles []string `json:",omitempty"` // _test.go files outside package
+	XTestImports []string `json:",omitempty"` // imports from XTestGoFiles
+
+	// Unexported fields are not part of the public API.
+	build        *build.Package
+	pkgdir       string // overrides build.PkgDir
+	imports      []*Package
+	deps         []*Package
+	gofiles      []string // GoFiles+CgoFiles+TestGoFiles+XTestGoFiles files, absolute paths
+	sfiles       []string
+	allgofiles   []string             // gofiles + IgnoredGoFiles, absolute paths
+	target       string               // installed file for this package (may be executable)
+	fake         bool                 // synthesized package
+	forceBuild   bool                 // this package must be rebuilt
+	forceLibrary bool                 // this package is a library (even if named "main")
+	cmdline      bool                 // defined by files listed on command line
+	local        bool                 // imported via local path (./ or ../)
+	localPrefix  string               // interpret ./ and ../ imports relative to this prefix
+	exeName      string               // desired name for temporary executable
+	coverMode    string               // preprocess Go source files with the coverage tool in this mode
+	coverVars    map[string]*CoverVar // variables created by coverage analysis
+	omitDWARF    bool                 // tell linker not to write DWARF information
+}
+
+// CoverVar holds the name of the generated coverage variables targeting the named file.
+type CoverVar struct {
+	File string // local file name
+	Var  string // name of count struct
+}
+
+func (p *Package) copyBuild(pp *build.Package) {
+	p.build = pp
+
+	p.Dir = pp.Dir
+	p.ImportPath = pp.ImportPath
+	p.Name = pp.Name
+	p.Doc = pp.Doc
+	p.Root = pp.Root
+	p.ConflictDir = pp.ConflictDir
+	// TODO? Target
+	p.Goroot = pp.Goroot
+	p.Standard = p.Goroot && p.ImportPath != "" && !strings.Contains(p.ImportPath, ".")
+	p.GoFiles = pp.GoFiles
+	p.CgoFiles = pp.CgoFiles
+	p.IgnoredGoFiles = pp.IgnoredGoFiles
+	p.CFiles = pp.CFiles
+	p.CXXFiles = pp.CXXFiles
+	p.MFiles = pp.MFiles
+	p.HFiles = pp.HFiles
+	p.SFiles = pp.SFiles
+	p.SwigFiles = pp.SwigFiles
+	p.SwigCXXFiles = pp.SwigCXXFiles
+	p.SysoFiles = pp.SysoFiles
+	p.CgoCFLAGS = pp.CgoCFLAGS
+	p.CgoCPPFLAGS = pp.CgoCPPFLAGS
+	p.CgoCXXFLAGS = pp.CgoCXXFLAGS
+	p.CgoLDFLAGS = pp.CgoLDFLAGS
+	p.CgoPkgConfig = pp.CgoPkgConfig
+	p.Imports = pp.Imports
+	p.TestGoFiles = pp.TestGoFiles
+	p.TestImports = pp.TestImports
+	p.XTestGoFiles = pp.XTestGoFiles
+	p.XTestImports = pp.XTestImports
+}
+
+// A PackageError describes an error loading information about a package.
+type PackageError struct {
+	ImportStack   []string // shortest path from package named on command line to this one
+	Pos           string   // position of error
+	Err           string   // the error itself
+	isImportCycle bool     // the error is an import cycle
+	hard          bool     // whether the error is soft or hard; soft errors are ignored in some places
+}
+
+func (p *PackageError) Error() string {
+	// Import cycles deserve special treatment.
+	if p.isImportCycle {
+		return fmt.Sprintf("%s\npackage %s\n", p.Err, strings.Join(p.ImportStack, "\n\timports "))
+	}
+	if p.Pos != "" {
+		// Omit import stack.  The full path to the file where the error
+		// is the most important thing.
+		return p.Pos + ": " + p.Err
+	}
+	if len(p.ImportStack) == 0 {
+		return p.Err
+	}
+	return "package " + strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Err
+}
+
+// An importStack is a stack of import paths.
+type importStack []string
+
+func (s *importStack) push(p string) {
+	*s = append(*s, p)
+}
+
+func (s *importStack) pop() {
+	*s = (*s)[0 : len(*s)-1]
+}
+
+func (s *importStack) copy() []string {
+	return append([]string{}, *s...)
+}
+
+// shorterThan returns true if sp is shorter than t.
+// We use this to record the shortest import sequence
+// that leads to a particular package.
+func (sp *importStack) shorterThan(t []string) bool {
+	s := *sp
+	if len(s) != len(t) {
+		return len(s) < len(t)
+	}
+	// If they are the same length, settle ties using string ordering.
+	for i := range s {
+		if s[i] != t[i] {
+			return s[i] < t[i]
+		}
+	}
+	return false // they are equal
+}
+
+// packageCache is a lookup cache for loadPackage,
+// so that if we look up a package multiple times
+// we return the same pointer each time.
+var packageCache = map[string]*Package{}
+
+// reloadPackage is like loadPackage but makes sure
+// not to use the package cache.
+func reloadPackage(arg string, stk *importStack) *Package {
+	p := packageCache[arg]
+	if p != nil {
+		delete(packageCache, p.Dir)
+		delete(packageCache, p.ImportPath)
+	}
+	return loadPackage(arg, stk)
+}
+
+// dirToImportPath returns the pseudo-import path we use for a package
+// outside the Go path.  It begins with _/ and then contains the full path
+// to the directory.  If the package lives in c:\home\gopher\my\pkg then
+// the pseudo-import path is _/c_/home/gopher/my/pkg.
+// Using a pseudo-import path like this makes the ./ imports no longer
+// a special case, so that all the code to deal with ordinary imports works
+// automatically.
+func dirToImportPath(dir string) string {
+	return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir)))
+}
+
+func makeImportValid(r rune) rune {
+	// Should match Go spec, compilers, and ../../pkg/go/parser/parser.go:/isValidImport.
+	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
+	if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
+		return '_'
+	}
+	return r
+}
+
+// loadImport scans the directory named by path, which must be an import path,
+// but possibly a local import path (an absolute file system path or one beginning
+// with ./ or ../).  A local relative path is interpreted relative to srcDir.
+// It returns a *Package describing the package found in that directory.
+func loadImport(path string, srcDir string, stk *importStack, importPos []token.Position) *Package {
+	stk.push(path)
+	defer stk.pop()
+
+	// Determine canonical identifier for this package.
+	// For a local import the identifier is the pseudo-import path
+	// we create from the full directory to the package.
+	// Otherwise it is the usual import path.
+	importPath := path
+	isLocal := build.IsLocalImport(path)
+	if isLocal {
+		importPath = dirToImportPath(filepath.Join(srcDir, path))
+	}
+	if p := packageCache[importPath]; p != nil {
+		return reusePackage(p, stk)
+	}
+
+	p := new(Package)
+	p.local = isLocal
+	p.ImportPath = importPath
+	packageCache[importPath] = p
+
+	// Load package.
+	// Import always returns bp != nil, even if an error occurs,
+	// in order to return partial information.
+	//
+	// TODO: After Go 1, decide when to pass build.AllowBinary here.
+	// See issue 3268 for mistakes to avoid.
+	bp, err := buildContext.Import(path, srcDir, 0)
+	bp.ImportPath = importPath
+	if gobin != "" {
+		bp.BinDir = gobin
+	}
+	p.load(stk, bp, err)
+	if p.Error != nil && len(importPos) > 0 {
+		pos := importPos[0]
+		pos.Filename = shortPath(pos.Filename)
+		p.Error.Pos = pos.String()
+	}
+
+	return p
+}
+
+// reusePackage reuses package p to satisfy the import at the top
+// of the import stack stk.  If this use causes an import loop,
+// reusePackage updates p's error information to record the loop.
+func reusePackage(p *Package, stk *importStack) *Package {
+	// We use p.imports==nil to detect a package that
+	// is in the midst of its own loadPackage call
+	// (all the recursion below happens before p.imports gets set).
+	if p.imports == nil {
+		if p.Error == nil {
+			p.Error = &PackageError{
+				ImportStack:   stk.copy(),
+				Err:           "import cycle not allowed",
+				isImportCycle: true,
+			}
+		}
+		p.Incomplete = true
+	}
+	// Don't rewrite the import stack in the error if we have an import cycle.
+	// If we do, we'll lose the path that describes the cycle.
+	if p.Error != nil && !p.Error.isImportCycle && stk.shorterThan(p.Error.ImportStack) {
+		p.Error.ImportStack = stk.copy()
+	}
+	return p
+}
+
+type targetDir int
+
+const (
+	toRoot targetDir = iota // to bin dir inside package root (default)
+	toTool                  // GOROOT/pkg/tool
+	toBin                   // GOROOT/bin
+)
+
+// goTools is a map of Go program import path to install target directory.
+var goTools = map[string]targetDir{
+	"cmd/addr2line":                        toTool,
+	"cmd/api":                              toTool,
+	"cmd/cgo":                              toTool,
+	"cmd/fix":                              toTool,
+	"cmd/link":                             toTool,
+	"cmd/nm":                               toTool,
+	"cmd/objdump":                          toTool,
+	"cmd/pack":                             toTool,
+	"cmd/yacc":                             toTool,
+	"code.google.com/p/go.tools/cmd/cover": toTool,
+	"code.google.com/p/go.tools/cmd/godoc": toBin,
+	"code.google.com/p/go.tools/cmd/vet":   toTool,
+}
+
+// expandScanner expands a scanner.List error into all the errors in the list.
+// The default Error method only shows the first error.
+func expandScanner(err error) error {
+	// Look for parser errors.
+	if err, ok := err.(scanner.ErrorList); ok {
+		// Prepare error with \n before each message.
+		// When printed in something like context: %v
+		// this will put the leading file positions each on
+		// its own line.  It will also show all the errors
+		// instead of just the first, as err.Error does.
+		var buf bytes.Buffer
+		for _, e := range err {
+			e.Pos.Filename = shortPath(e.Pos.Filename)
+			buf.WriteString("\n")
+			buf.WriteString(e.Error())
+		}
+		return errors.New(buf.String())
+	}
+	return err
+}
+
+var raceExclude = map[string]bool{
+	"runtime/race": true,
+	"runtime/cgo":  true,
+	"cmd/cgo":      true,
+	"syscall":      true,
+	"errors":       true,
+}
+
+var cgoExclude = map[string]bool{
+	"runtime/cgo": true,
+}
+
+var cgoSyscallExclude = map[string]bool{
+	"runtime/cgo":  true,
+	"runtime/race": true,
+}
+
+// load populates p using information from bp, err, which should
+// be the result of calling build.Context.Import.
+func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package {
+	p.copyBuild(bp)
+
+	// The localPrefix is the path we interpret ./ imports relative to.
+	// Synthesized main packages sometimes override this.
+	p.localPrefix = dirToImportPath(p.Dir)
+
+	if err != nil {
+		p.Incomplete = true
+		err = expandScanner(err)
+		p.Error = &PackageError{
+			ImportStack: stk.copy(),
+			Err:         err.Error(),
+		}
+		return p
+	}
+
+	if p.Name == "main" {
+		_, elem := filepath.Split(p.Dir)
+		full := buildContext.GOOS + "_" + buildContext.GOARCH + "/" + elem
+		if buildContext.GOOS != toolGOOS || buildContext.GOARCH != toolGOARCH {
+			// Install cross-compiled binaries to subdirectories of bin.
+			elem = full
+		}
+		if p.build.BinDir != gobin && goTools[p.ImportPath] == toBin {
+			// Override BinDir.
+			// This is from a subrepo but installs to $GOROOT/bin
+			// by default anyway (like godoc).
+			p.target = filepath.Join(gorootBin, elem)
+		} else if p.build.BinDir != "" {
+			// Install to GOBIN or bin of GOPATH entry.
+			p.target = filepath.Join(p.build.BinDir, elem)
+		}
+		if goTools[p.ImportPath] == toTool {
+			// This is for 'go tool'.
+			// Override all the usual logic and force it into the tool directory.
+			p.target = filepath.Join(gorootPkg, "tool", full)
+		}
+		if p.target != "" && buildContext.GOOS == "windows" {
+			p.target += ".exe"
+		}
+	} else if p.local {
+		// Local import turned into absolute path.
+		// No permanent install target.
+		p.target = ""
+	} else {
+		p.target = p.build.PkgObj
+	}
+
+	importPaths := p.Imports
+	// Packages that use cgo import runtime/cgo implicitly.
+	// Packages that use cgo also import syscall implicitly,
+	// to wrap errno.
+	// Exclude certain packages to avoid circular dependencies.
+	if len(p.CgoFiles) > 0 && (!p.Standard || !cgoExclude[p.ImportPath]) {
+		importPaths = append(importPaths, "runtime/cgo")
+	}
+	if len(p.CgoFiles) > 0 && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
+		importPaths = append(importPaths, "syscall")
+	}
+	// Everything depends on runtime, except runtime and unsafe.
+	if !p.Standard || (p.ImportPath != "runtime" && p.ImportPath != "unsafe") {
+		importPaths = append(importPaths, "runtime")
+		// When race detection enabled everything depends on runtime/race.
+		// Exclude certain packages to avoid circular dependencies.
+		if buildRace && (!p.Standard || !raceExclude[p.ImportPath]) {
+			importPaths = append(importPaths, "runtime/race")
+		}
+	}
+
+	// Build list of full paths to all Go files in the package,
+	// for use by commands like go fmt.
+	p.gofiles = stringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)
+	for i := range p.gofiles {
+		p.gofiles[i] = filepath.Join(p.Dir, p.gofiles[i])
+	}
+	sort.Strings(p.gofiles)
+
+	p.sfiles = stringList(p.SFiles)
+	for i := range p.sfiles {
+		p.sfiles[i] = filepath.Join(p.Dir, p.sfiles[i])
+	}
+	sort.Strings(p.sfiles)
+
+	p.allgofiles = stringList(p.IgnoredGoFiles)
+	for i := range p.allgofiles {
+		p.allgofiles[i] = filepath.Join(p.Dir, p.allgofiles[i])
+	}
+	p.allgofiles = append(p.allgofiles, p.gofiles...)
+	sort.Strings(p.allgofiles)
+
+	// Check for case-insensitive collision of input files.
+	// To avoid problems on case-insensitive files, we reject any package
+	// where two different input files have equal names under a case-insensitive
+	// comparison.
+	f1, f2 := foldDup(stringList(
+		p.GoFiles,
+		p.CgoFiles,
+		p.IgnoredGoFiles,
+		p.CFiles,
+		p.CXXFiles,
+		p.MFiles,
+		p.HFiles,
+		p.SFiles,
+		p.SysoFiles,
+		p.SwigFiles,
+		p.SwigCXXFiles,
+		p.TestGoFiles,
+		p.XTestGoFiles,
+	))
+	if f1 != "" {
+		p.Error = &PackageError{
+			ImportStack: stk.copy(),
+			Err:         fmt.Sprintf("case-insensitive file name collision: %q and %q", f1, f2),
+		}
+		return p
+	}
+
+	// Build list of imported packages and full dependency list.
+	imports := make([]*Package, 0, len(p.Imports))
+	deps := make(map[string]bool)
+	for i, path := range importPaths {
+		if path == "C" {
+			continue
+		}
+		p1 := loadImport(path, p.Dir, stk, p.build.ImportPos[path])
+		if !reqPkgSrc && p1.Root == "" {
+			continue
+		}
+		if p1.local {
+			if !p.local && p.Error == nil {
+				p.Error = &PackageError{
+					ImportStack: stk.copy(),
+					Err:         fmt.Sprintf("local import %q in non-local package", path),
+				}
+				pos := p.build.ImportPos[path]
+				if len(pos) > 0 {
+					p.Error.Pos = pos[0].String()
+				}
+			}
+			path = p1.ImportPath
+			importPaths[i] = path
+		}
+		deps[path] = true
+		imports = append(imports, p1)
+		for _, dep := range p1.Deps {
+			deps[dep] = true
+		}
+		if p1.Incomplete {
+			p.Incomplete = true
+		}
+	}
+	p.imports = imports
+
+	p.Deps = make([]string, 0, len(deps))
+	for dep := range deps {
+		p.Deps = append(p.Deps, dep)
+	}
+	sort.Strings(p.Deps)
+	for _, dep := range p.Deps {
+		p1 := packageCache[dep]
+		if p1 == nil {
+			panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath)
+		}
+		p.deps = append(p.deps, p1)
+		if p1.Error != nil {
+			p.DepsErrors = append(p.DepsErrors, p1.Error)
+		}
+	}
+
+	// unsafe is a fake package.
+	if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") {
+		p.target = ""
+	}
+	p.Target = p.target
+
+	// In the absence of errors lower in the dependency tree,
+	// check for case-insensitive collisions of import paths.
+	if len(p.DepsErrors) == 0 {
+		dep1, dep2 := foldDup(p.Deps)
+		if dep1 != "" {
+			p.Error = &PackageError{
+				ImportStack: stk.copy(),
+				Err:         fmt.Sprintf("case-insensitive import collision: %q and %q", dep1, dep2),
+			}
+			return p
+		}
+	}
+
+	return p
+}
+
+// usesSwig reports whether the package needs to run SWIG.
+func (p *Package) usesSwig() bool {
+	return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0
+}
+
+// usesCgo reports whether the package needs to run cgo
+func (p *Package) usesCgo() bool {
+	return len(p.CgoFiles) > 0
+}
+
+// packageList returns the list of packages in the dag rooted at roots
+// as visited in a depth-first post-order traversal.
+func packageList(roots []*Package) []*Package {
+	seen := map[*Package]bool{}
+	all := []*Package{}
+	var walk func(*Package)
+	walk = func(p *Package) {
+		if seen[p] {
+			return
+		}
+		seen[p] = true
+		for _, p1 := range p.imports {
+			walk(p1)
+		}
+		all = append(all, p)
+	}
+	for _, root := range roots {
+		walk(root)
+	}
+	return all
+}
+
+// computeStale computes the Stale flag in the package dag that starts
+// at the named pkgs (command-line arguments).
+func computeStale(pkgs ...*Package) {
+	topRoot := map[string]bool{}
+	for _, p := range pkgs {
+		topRoot[p.Root] = true
+	}
+
+	for _, p := range packageList(pkgs) {
+		p.Stale = isStale(p, topRoot)
+	}
+}
+
+// isStale reports whether package p needs to be rebuilt.
+func isStale(p *Package, topRoot map[string]bool) bool {
+	if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") {
+		// fake, builtin package
+		return false
+	}
+	if p.Error != nil {
+		return true
+	}
+
+	// A package without Go sources means we only found
+	// the installed .a file.  Since we don't know how to rebuild
+	// it, it can't be stale, even if -a is set.  This enables binary-only
+	// distributions of Go packages, although such binaries are
+	// only useful with the specific version of the toolchain that
+	// created them.
+	if len(p.gofiles) == 0 && !p.usesSwig() {
+		return false
+	}
+
+	if buildA || p.target == "" || p.Stale {
+		return true
+	}
+
+	// Package is stale if completely unbuilt.
+	var built time.Time
+	if fi, err := os.Stat(p.target); err == nil {
+		built = fi.ModTime()
+	}
+	if built.IsZero() {
+		return true
+	}
+
+	olderThan := func(file string) bool {
+		fi, err := os.Stat(file)
+		return err != nil || fi.ModTime().After(built)
+	}
+
+	// Package is stale if a dependency is, or if a dependency is newer.
+	for _, p1 := range p.deps {
+		if p1.Stale || p1.target != "" && olderThan(p1.target) {
+			return true
+		}
+	}
+
+	// As a courtesy to developers installing new versions of the compiler
+	// frequently, define that packages are stale if they are
+	// older than the compiler, and commands if they are older than
+	// the linker.  This heuristic will not work if the binaries are
+	// back-dated, as some binary distributions may do, but it does handle
+	// a very common case.
+	// See issue 3036.
+	// Assume code in $GOROOT is up to date, since it may not be writeable.
+	// See issue 4106.
+	if p.Root != goroot {
+		if olderThan(buildToolchain.compiler()) {
+			return true
+		}
+		if p.build.IsCommand() && olderThan(buildToolchain.linker()) {
+			return true
+		}
+	}
+
+	// Have installed copy, probably built using current compilers,
+	// and built after its imported packages.  The only reason now
+	// that we'd have to rebuild it is if the sources were newer than
+	// the package.   If a package p is not in the same tree as any
+	// package named on the command-line, assume it is up-to-date
+	// no matter what the modification times on the source files indicate.
+	// This avoids rebuilding $GOROOT packages when people are
+	// working outside the Go root, and it effectively makes each tree
+	// listed in $GOPATH a separate compilation world.
+	// See issue 3149.
+	if p.Root != "" && !topRoot[p.Root] {
+		return false
+	}
+
+	srcs := stringList(p.GoFiles, p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.SFiles, p.CgoFiles, p.SysoFiles, p.SwigFiles, p.SwigCXXFiles)
+	for _, src := range srcs {
+		if olderThan(filepath.Join(p.Dir, src)) {
+			return true
+		}
+	}
+
+	return false
+}
+
+var cwd, _ = os.Getwd()
+
+var cmdCache = map[string]*Package{}
+
+// loadPackage is like loadImport but is used for command-line arguments,
+// not for paths found in import statements.  In addition to ordinary import paths,
+// loadPackage accepts pseudo-paths beginning with cmd/ to denote commands
+// in the Go command directory, as well as paths to those directories.
+func loadPackage(arg string, stk *importStack) *Package {
+	if build.IsLocalImport(arg) {
+		dir := arg
+		if !filepath.IsAbs(dir) {
+			if abs, err := filepath.Abs(dir); err == nil {
+				// interpret relative to current directory
+				dir = abs
+			}
+		}
+		if sub, ok := hasSubdir(gorootSrc, dir); ok && strings.HasPrefix(sub, "cmd/") && !strings.Contains(sub[4:], "/") {
+			arg = sub
+		}
+	}
+	if strings.HasPrefix(arg, "cmd/") {
+		if p := cmdCache[arg]; p != nil {
+			return p
+		}
+		stk.push(arg)
+		defer stk.pop()
+
+		if strings.Contains(arg[4:], "/") {
+			p := &Package{
+				Error: &PackageError{
+					ImportStack: stk.copy(),
+					Err:         fmt.Sprintf("invalid import path: cmd/... is reserved for Go commands"),
+					hard:        true,
+				},
+			}
+			return p
+		}
+
+		bp, err := buildContext.ImportDir(filepath.Join(gorootSrc, arg), 0)
+		bp.ImportPath = arg
+		bp.Goroot = true
+		bp.BinDir = gorootBin
+		if gobin != "" {
+			bp.BinDir = gobin
+		}
+		bp.Root = goroot
+		bp.SrcRoot = gorootSrc
+		p := new(Package)
+		cmdCache[arg] = p
+		p.load(stk, bp, err)
+		if p.Error == nil && p.Name != "main" {
+			p.Error = &PackageError{
+				ImportStack: stk.copy(),
+				Err:         fmt.Sprintf("expected package main but found package %s in %s", p.Name, p.Dir),
+			}
+		}
+		return p
+	}
+
+	// Wasn't a command; must be a package.
+	// If it is a local import path but names a standard package,
+	// we treat it as if the user specified the standard package.
+	// This lets you run go test ./ioutil in package io and be
+	// referring to io/ioutil rather than a hypothetical import of
+	// "./ioutil".
+	if build.IsLocalImport(arg) {
+		bp, _ := buildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
+		if bp.ImportPath != "" && bp.ImportPath != "." {
+			arg = bp.ImportPath
+		}
+	}
+
+	return loadImport(arg, cwd, stk, nil)
+}
+
+// packages returns the packages named by the
+// command line arguments 'args'.  If a named package
+// cannot be loaded at all (for example, if the directory does not exist),
+// then packages prints an error and does not include that
+// package in the results.  However, if errors occur trying
+// to load dependencies of a named package, the named
+// package is still returned, with p.Incomplete = true
+// and details in p.DepsErrors.
+func packages(args []string) []*Package {
+	var pkgs []*Package
+	for _, pkg := range packagesAndErrors(args) {
+		if pkg.Error != nil {
+			errorf("can't load package: %s", pkg.Error)
+			continue
+		}
+		pkgs = append(pkgs, pkg)
+	}
+	return pkgs
+}
+
+// packagesAndErrors is like 'packages' but returns a
+// *Package for every argument, even the ones that
+// cannot be loaded at all.
+// The packages that fail to load will have p.Error != nil.
+func packagesAndErrors(args []string) []*Package {
+	if len(args) > 0 && strings.HasSuffix(args[0], ".go") {
+		return []*Package{goFilesPackage(args)}
+	}
+
+	args = importPaths(args)
+	var pkgs []*Package
+	var stk importStack
+	var set = make(map[string]bool)
+
+	for _, arg := range args {
+		if !set[arg] {
+			pkgs = append(pkgs, loadPackage(arg, &stk))
+			set[arg] = true
+		}
+	}
+	computeStale(pkgs...)
+
+	return pkgs
+}
+
+// packagesForBuild is like 'packages' but fails if any of
+// the packages or their dependencies have errors
+// (cannot be built).
+func packagesForBuild(args []string) []*Package {
+	pkgs := packagesAndErrors(args)
+	printed := map[*PackageError]bool{}
+	for _, pkg := range pkgs {
+		if pkg.Error != nil {
+			errorf("can't load package: %s", pkg.Error)
+		}
+		for _, err := range pkg.DepsErrors {
+			// Since these are errors in dependencies,
+			// the same error might show up multiple times,
+			// once in each package that depends on it.
+			// Only print each once.
+			if !printed[err] {
+				printed[err] = true
+				errorf("%s", err)
+			}
+		}
+	}
+	exitIfErrors()
+	return pkgs
+}
+
+// hasSubdir reports whether dir is a subdirectory of
+// (possibly multiple levels below) root.
+// If so, it sets rel to the path fragment that must be
+// appended to root to reach dir.
+func hasSubdir(root, dir string) (rel string, ok bool) {
+	if p, err := filepath.EvalSymlinks(root); err == nil {
+		root = p
+	}
+	if p, err := filepath.EvalSymlinks(dir); err == nil {
+		dir = p
+	}
+	const sep = string(filepath.Separator)
+	root = filepath.Clean(root)
+	if !strings.HasSuffix(root, sep) {
+		root += sep
+	}
+	dir = filepath.Clean(dir)
+	if !strings.HasPrefix(dir, root) {
+		return "", false
+	}
+	return filepath.ToSlash(dir[len(root):]), true
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/pkg_test.go b/third_party/gofrontend/libgo/go/cmd/go/pkg_test.go
new file mode 100644
index 0000000..06b9f0a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/pkg_test.go
@@ -0,0 +1,73 @@
+// 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 (
+	"reflect"
+	"strings"
+	"testing"
+)
+
+var foldDupTests = []struct {
+	list   []string
+	f1, f2 string
+}{
+	{stringList("math/rand", "math/big"), "", ""},
+	{stringList("math", "strings"), "", ""},
+	{stringList("strings"), "", ""},
+	{stringList("strings", "strings"), "strings", "strings"},
+	{stringList("Rand", "rand", "math", "math/rand", "math/Rand"), "Rand", "rand"},
+}
+
+func TestFoldDup(t *testing.T) {
+	for _, tt := range foldDupTests {
+		f1, f2 := foldDup(tt.list)
+		if f1 != tt.f1 || f2 != tt.f2 {
+			t.Errorf("foldDup(%q) = %q, %q, want %q, %q", tt.list, f1, f2, tt.f1, tt.f2)
+		}
+	}
+}
+
+var parseMetaGoImportsTests = []struct {
+	in  string
+	out []metaImport
+}{
+	{
+		`<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">`,
+		[]metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}},
+	},
+	{
+		`<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">
+		<meta name="go-import" content="baz/quux git http://github.com/rsc/baz/quux">`,
+		[]metaImport{
+			{"foo/bar", "git", "https://github.com/rsc/foo/bar"},
+			{"baz/quux", "git", "http://github.com/rsc/baz/quux"},
+		},
+	},
+	{
+		`<head>
+		<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">
+		</head>`,
+		[]metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}},
+	},
+	{
+		`<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">
+		<body>`,
+		[]metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}},
+	},
+}
+
+func TestParseMetaGoImports(t *testing.T) {
+	for i, tt := range parseMetaGoImportsTests {
+		out, err := parseMetaGoImports(strings.NewReader(tt.in))
+		if err != nil {
+			t.Errorf("test#%d: %v", i, err)
+			continue
+		}
+		if !reflect.DeepEqual(out, tt.out) {
+			t.Errorf("test#%d:\n\thave %q\n\twant %q", i, out, tt.out)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/run.go b/third_party/gofrontend/libgo/go/cmd/go/run.go
new file mode 100644
index 0000000..ef8aa95
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/run.go
@@ -0,0 +1,143 @@
+// Copyright 2011 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"
+	"os"
+	"os/exec"
+	"runtime"
+	"strings"
+)
+
+var execCmd []string // -exec flag, for run and test
+
+func findExecCmd() []string {
+	if execCmd != nil {
+		return execCmd
+	}
+	execCmd = []string{} // avoid work the second time
+	if goos == runtime.GOOS && goarch == runtime.GOARCH {
+		return execCmd
+	}
+	path, err := exec.LookPath(fmt.Sprintf("go_%s_%s_exec", goos, goarch))
+	if err == nil {
+		execCmd = []string{path}
+	}
+	return execCmd
+}
+
+var cmdRun = &Command{
+	UsageLine: "run [build flags] [-exec xprog] gofiles... [arguments...]",
+	Short:     "compile and run Go program",
+	Long: `
+Run compiles and runs the main package comprising the named Go source files.
+A Go source file is defined to be a file ending in a literal ".go" suffix.
+
+By default, 'go run' runs the compiled binary directly: 'a.out arguments...'.
+If the -exec flag is given, 'go run' invokes the binary using xprog: 'xprog a.out arguments...'.
+If the -exec flag is not given, GOOS or GOARCH is different from the system
+default, and a program named go_$GOOS_$GOARCH_exec can be found
+on the current search path, 'go run' invokes the binary using that program,
+for example 'go_nacl_386_exec a.out arguments...'. This allows execution of
+cross-compiled programs when a simulator or other execution method is
+available.
+
+For more about build flags, see 'go help build'.
+
+See also: go build.
+	`,
+}
+
+func init() {
+	cmdRun.Run = runRun // break init loop
+
+	addBuildFlags(cmdRun)
+	cmdRun.Flag.Var((*stringsFlag)(&execCmd), "exec", "")
+}
+
+func printStderr(args ...interface{}) (int, error) {
+	return fmt.Fprint(os.Stderr, args...)
+}
+
+func runRun(cmd *Command, args []string) {
+	raceInit()
+	var b builder
+	b.init()
+	b.print = printStderr
+	i := 0
+	for i < len(args) && strings.HasSuffix(args[i], ".go") {
+		i++
+	}
+	files, cmdArgs := args[:i], args[i:]
+	if len(files) == 0 {
+		fatalf("go run: no go files listed")
+	}
+	for _, file := range files {
+		if strings.HasSuffix(file, "_test.go") {
+			// goFilesPackage is going to assign this to TestGoFiles.
+			// Reject since it won't be part of the build.
+			fatalf("go run: cannot run *_test.go files (%s)", file)
+		}
+	}
+	p := goFilesPackage(files)
+	if p.Error != nil {
+		fatalf("%s", p.Error)
+	}
+	p.omitDWARF = true
+	for _, err := range p.DepsErrors {
+		errorf("%s", err)
+	}
+	exitIfErrors()
+	if p.Name != "main" {
+		fatalf("go run: cannot run non-main package")
+	}
+	p.target = "" // must build - not up to date
+	var src string
+	if len(p.GoFiles) > 0 {
+		src = p.GoFiles[0]
+	} else if len(p.CgoFiles) > 0 {
+		src = p.CgoFiles[0]
+	} else {
+		// this case could only happen if the provided source uses cgo
+		// while cgo is disabled.
+		hint := ""
+		if !buildContext.CgoEnabled {
+			hint = " (cgo is disabled)"
+		}
+		fatalf("go run: no suitable source files%s", hint)
+	}
+	p.exeName = src[:len(src)-len(".go")] // name temporary executable for first go file
+	a1 := b.action(modeBuild, modeBuild, p)
+	a := &action{f: (*builder).runProgram, args: cmdArgs, deps: []*action{a1}}
+	b.do(a)
+}
+
+// runProgram is the action for running a binary that has already
+// been compiled.  We ignore exit status.
+func (b *builder) runProgram(a *action) error {
+	cmdline := stringList(findExecCmd(), a.deps[0].target, a.args)
+	if buildN || buildX {
+		b.showcmd("", "%s", strings.Join(cmdline, " "))
+		if buildN {
+			return nil
+		}
+	}
+
+	runStdin(cmdline)
+	return nil
+}
+
+// runStdin is like run, but connects Stdin.
+func runStdin(cmdline []string) {
+	cmd := exec.Command(cmdline[0], cmdline[1:]...)
+	cmd.Stdin = os.Stdin
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	startSigHandlers()
+	if err := cmd.Run(); err != nil {
+		errorf("%v", err)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/script b/third_party/gofrontend/libgo/go/cmd/go/script
new file mode 100755
index 0000000..340a7e8
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/script
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+x() {
+	echo '--- ' "$@"
+	"$@"
+	echo '---'
+	echo
+}
+
+x go help
+x go help build
+x go help clean
+x go help install
+x go help fix
+x go help fmt
+x go help get
+x go help list
+x go help test
+x go help version
+x go help vet
+x go help gopath
+x go help importpath
+x go help remote
diff --git a/third_party/gofrontend/libgo/go/cmd/go/script.txt b/third_party/gofrontend/libgo/go/cmd/go/script.txt
new file mode 100644
index 0000000..a672146
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/script.txt
@@ -0,0 +1,352 @@
+---  go help
+usage: go command [arguments]
+
+go manages Go source code.
+
+The commands are:
+
+    build       compile and install packages and dependencies
+    clean       remove intermediate objects
+    fix         run gofix on packages
+    fmt         run gofmt -w on packages
+    get         download and install packages and dependencies
+    install     install packages and dependencies
+    list        list packages
+    test        test packages
+    version     print Go version
+    vet         run govet on packages
+
+Use "go help [command]" for more information about a command.
+
+Additional help topics:
+
+    gopath      GOPATH environment variable
+    importpath  description of import paths
+    remote      remote import path syntax
+
+Use "go help [topic]" for more information about that topic.
+
+---
+
+---  go help build
+usage: go build [-n] [-v] [importpath...]
+
+Build compiles the packages named by the import paths,
+along with their dependencies, but it does not install the results.
+
+The -n flag prints the commands but does not run them.
+The -v flag prints the commands.
+
+For more about import paths, see 'go help importpath'.
+
+See also: go install, go get, go clean.
+---
+
+---  go help clean
+usage: go clean [-nuke] [importpath...]
+
+Clean removes intermediate object files generated during
+the compilation of the packages named by the import paths,
+but by default it does not remove the installed package binaries.
+
+The -nuke flag causes clean to remove the installed package binaries too.
+
+TODO: Clean does not clean dependencies of the packages.
+
+For more about import paths, see 'go help importpath'.
+---
+
+---  go help install
+usage: go install [-n] [-v] [importpath...]
+
+Install compiles and installs the packages named by the import paths,
+along with their dependencies.
+
+The -n flag prints the commands but does not run them.
+The -v flag prints the commands.
+
+For more about import paths, see 'go help importpath'.
+
+See also: go build, go get, go clean.
+---
+
+---  go help fix
+usage: go fix [importpath...]
+
+Fix runs the gofix command on the packages named by the import paths.
+
+For more about gofix, see 'godoc gofix'.
+For more about import paths, see 'go help importpath'.
+
+To run gofix with specific options, run gofix itself.
+
+See also: go fmt, go vet.
+---
+
+---  go help fmt
+usage: go fmt [importpath...]
+
+Fmt runs the command 'gofmt -w' on the packages named by the import paths.
+
+For more about gofmt, see 'godoc gofmt'.
+For more about import paths, see 'go help importpath'.
+
+To run gofmt with specific options, run gofmt itself.
+
+See also: go fix, go vet.
+---
+
+---  go help get
+usage: go get [importpath...]
+
+Get downloads and installs the packages named by the import paths,
+along with their dependencies.
+
+After downloading the code, 'go get' looks for a tag beginning
+with "go." that corresponds to the local Go version.
+For Go "release.r58" it looks for a tag named "go.r58".
+For "weekly.2011-06-03" it looks for "go.weekly.2011-06-03".
+If the specific "go.X" tag is not found, it uses the latest earlier
+version it can find.  Otherwise, it uses the default version for
+the version control system: HEAD for git, tip for Mercurial,
+and so on.
+
+TODO: Explain versions better.
+
+For more about import paths, see 'go help importpath'.
+
+For more about how 'go get' finds source code to
+download, see 'go help remote'.
+
+See also: go build, go install, go clean.
+---
+
+---  go help list
+usage: go list [-f format] [-json] [importpath...]
+
+List lists the packages named by the import paths.
+
+The default output shows the package name and file system location:
+
+    books /home/you/src/google-api-go-client.googlecode.com/hg/books/v1
+    oauth /home/you/src/goauth2.googlecode.com/hg/oauth
+    sqlite /home/you/src/gosqlite.googlecode.com/hg/sqlite
+
+The -f flag specifies an alternate format for the list,
+using the syntax of package template.  The default output
+is equivalent to -f '{{.Name}} {{.Dir}}'  The struct
+being passed to the template is:
+
+    type Package struct {
+        Name string         // package name
+        Doc string          // package documentation string
+        GoFiles []string    // names of Go source files in package
+        ImportPath string   // import path denoting package
+        Imports []string    // import paths used by this package
+        Deps []string       // all (recursively) imported dependencies
+        Dir string          // directory containing package sources
+        Version string      // version of installed package
+    }
+
+The -json flag causes the package data to be printed in JSON format.
+
+For more about import paths, see 'go help importpath'.
+---
+
+---  go help test
+usage: go test [importpath...]
+
+Test runs gotest to test the packages named by the import paths.
+It prints a summary of the test results in the format:
+
+	test archive/tar
+	FAIL archive/zip
+	test compress/gzip
+	...
+
+followed by gotest output for each failed package.
+
+For more about import paths, see 'go help importpath'.
+
+See also: go build, go compile, go vet.
+---
+
+---  go help version
+usage: go version
+
+Version prints the Go version, as reported by runtime.Version.
+---
+
+---  go help vet
+usage: go vet [importpath...]
+
+Vet runs the govet command on the packages named by the import paths.
+
+For more about govet, see 'godoc govet'.
+For more about import paths, see 'go help importpath'.
+
+To run govet with specific options, run govet itself.
+
+See also: go fmt, go fix.
+---
+
+---  go help gopath
+The GOPATH environment variable lists places to look for Go code.
+On Unix, the value is a colon-separated string.
+On Windows, the value is a semicolon-separated string.
+On Plan 9, the value is a list.
+
+GOPATH must be set to build and install packages outside the
+standard Go tree.
+
+Each directory listed in GOPATH must have a prescribed structure:
+
+The src/ directory holds source code.  The path below 'src'
+determines the import path or executable name.
+
+The pkg/ directory holds installed package objects.
+As in the Go tree, each target operating system and
+architecture pair has its own subdirectory of pkg
+(pkg/GOOS_GOARCH).
+
+If DIR is a directory listed in the GOPATH, a package with
+source in DIR/src/foo/bar can be imported as "foo/bar" and
+has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a".
+
+The bin/ directory holds compiled commands.
+Each command is named for its source directory, but only
+the final element, not the entire path.  That is, the
+command with source in DIR/src/foo/quux is installed into
+DIR/bin/quux, not DIR/bin/foo/quux.  The foo/ is stripped
+so that you can add DIR/bin to your PATH to get at the
+installed commands.
+
+Here's an example directory layout:
+
+    GOPATH=/home/user/gocode
+
+    /home/user/gocode/
+        src/
+            foo/
+                bar/               (go code in package bar)
+                    x.go
+                quux/              (go code in package main)
+                    y.go
+        bin/
+            quux                   (installed command)
+		pkg/
+		    linux_amd64/
+		        foo/
+		            bar.a          (installed package object)
+
+Go searches each directory listed in GOPATH to find source code,
+but new packages are always downloaded into the first directory 
+in the list.
+---
+
+---  go help importpath
+Many commands apply to a set of packages named by import paths:
+
+	go action [importpath...]
+
+An import path that is a rooted path or that begins with
+a . or .. element is interpreted as a file system path and
+denotes the package in that directory.
+
+Otherwise, the import path P denotes the package found in
+the directory DIR/src/P for some DIR listed in the GOPATH
+environment variable (see 'go help gopath'). 
+
+If no import paths are given, the action applies to the
+package in the current directory.
+
+The special import path "all" expands to all package directories
+found in all the GOPATH trees.  For example, 'go list all' 
+lists all the packages on the local system.
+
+An import path can also name a package to be downloaded from
+a remote repository.  Run 'go help remote' for details.
+
+Every package in a program must have a unique import path.
+By convention, this is arranged by starting each path with a
+unique prefix that belongs to you.  For example, paths used
+internally at Google all begin with 'google', and paths
+denoting remote repositories begin with the path to the code,
+such as 'project.googlecode.com/'.
+---
+
+---  go help remote
+An import path (see 'go help importpath') denotes a package
+stored in the local file system.  Certain import paths also
+describe how to obtain the source code for the package using
+a revision control system.
+
+A few common code hosting sites have special syntax:
+
+	BitBucket (Mercurial)
+
+		import "bitbucket.org/user/project"
+		import "bitbucket.org/user/project/sub/directory"
+
+	GitHub (Git)
+
+		import "github.com/user/project"
+		import "github.com/user/project/sub/directory"
+
+	Google Code Project Hosting (Git, Mercurial, Subversion)
+
+		import "project.googlecode.com/git"
+		import "project.googlecode.com/git/sub/directory"
+
+		import "project.googlecode.com/hg"
+		import "project.googlecode.com/hg/sub/directory"
+
+		import "project.googlecode.com/svn/trunk"
+		import "project.googlecode.com/svn/trunk/sub/directory"
+
+	Launchpad (Bazaar)
+
+		import "launchpad.net/project"
+		import "launchpad.net/project/series"
+		import "launchpad.net/project/series/sub/directory"
+
+		import "launchpad.net/~user/project/branch"
+		import "launchpad.net/~user/project/branch/sub/directory"
+
+For code hosted on other servers, an import path of the form
+
+	repository.vcs/path
+
+specifies the given repository, with or without the .vcs suffix,
+using the named version control system, and then the path inside
+that repository.  The supported version control systems are:
+
+	Bazaar      .bzr
+	Git         .git
+	Mercurial   .hg
+	Subversion  .svn
+
+For example,
+
+	import "example.org/user/foo.hg"
+
+denotes the root directory of the Mercurial repository at
+example.org/user/foo or foo.hg, and
+
+	import "example.org/repo.git/foo/bar"
+
+denotes the foo/bar directory of the Git repository at
+example.com/repo or repo.git.
+
+When a version control system supports multiple protocols,
+each is tried in turn when downloading.  For example, a Git
+download tries git://, then https://, then http://.
+
+New downloaded packages are written to the first directory
+listed in the GOPATH environment variable (see 'go help gopath').
+
+The go command attempts to download the version of the
+package appropriate for the Go release being used.
+Run 'go help install' for more.
+---
+
diff --git a/third_party/gofrontend/libgo/go/cmd/go/signal.go b/third_party/gofrontend/libgo/go/cmd/go/signal.go
new file mode 100644
index 0000000..e8ba0d3
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/signal.go
@@ -0,0 +1,31 @@
+// 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 main
+
+import (
+	"os"
+	"os/signal"
+	"sync"
+)
+
+// interrupted is closed, if go process is interrupted.
+var interrupted = make(chan struct{})
+
+// processSignals setups signal handler.
+func processSignals() {
+	sig := make(chan os.Signal)
+	signal.Notify(sig, signalsToIgnore...)
+	go func() {
+		<-sig
+		close(interrupted)
+	}()
+}
+
+var onceProcessSignals sync.Once
+
+// startSigHandlers start signal handlers.
+func startSigHandlers() {
+	onceProcessSignals.Do(processSignals)
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/signal_notunix.go b/third_party/gofrontend/libgo/go/cmd/go/signal_notunix.go
new file mode 100644
index 0000000..29aa9d8
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/signal_notunix.go
@@ -0,0 +1,17 @@
+// 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.
+
+// +build plan9 windows
+
+package main
+
+import (
+	"os"
+)
+
+var signalsToIgnore = []os.Signal{os.Interrupt}
+
+// signalTrace is the signal to send to make a Go program
+// crash with a stack trace.
+var signalTrace os.Signal = nil
diff --git a/third_party/gofrontend/libgo/go/cmd/go/signal_unix.go b/third_party/gofrontend/libgo/go/cmd/go/signal_unix.go
new file mode 100644
index 0000000..e86cd46
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/signal_unix.go
@@ -0,0 +1,18 @@
+// 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.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package main
+
+import (
+	"os"
+	"syscall"
+)
+
+var signalsToIgnore = []os.Signal{os.Interrupt, syscall.SIGQUIT}
+
+// signalTrace is the signal to send to make a Go program
+// crash with a stack trace.
+var signalTrace os.Signal = syscall.SIGQUIT
diff --git a/third_party/gofrontend/libgo/go/cmd/go/tag_test.go b/third_party/gofrontend/libgo/go/cmd/go/tag_test.go
new file mode 100644
index 0000000..ffe218c
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/tag_test.go
@@ -0,0 +1,100 @@
+// Copyright 2011 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 "testing"
+
+var selectTagTestTags = []string{
+	"go.r58",
+	"go.r58.1",
+	"go.r59",
+	"go.r59.1",
+	"go.r61",
+	"go.r61.1",
+	"go.weekly.2010-01-02",
+	"go.weekly.2011-10-12",
+	"go.weekly.2011-10-12.1",
+	"go.weekly.2011-10-14",
+	"go.weekly.2011-11-01",
+	"go1",
+	"go1.0.1",
+	"go1.999",
+	"go1.9.2",
+	"go5",
+
+	// these should be ignored:
+	"release.r59",
+	"release.r59.1",
+	"release",
+	"weekly.2011-10-12",
+	"weekly.2011-10-12.1",
+	"weekly",
+	"foo",
+	"bar",
+	"go.f00",
+	"go!r60",
+	"go.1999-01-01",
+	"go.2x",
+	"go.20000000000000",
+	"go.2.",
+	"go.2.0",
+	"go2x",
+	"go20000000000000",
+	"go2.",
+	"go2.0",
+}
+
+var selectTagTests = []struct {
+	version  string
+	selected string
+}{
+	/*
+		{"release.r57", ""},
+		{"release.r58.2", "go.r58.1"},
+		{"release.r59", "go.r59"},
+		{"release.r59.1", "go.r59.1"},
+		{"release.r60", "go.r59.1"},
+		{"release.r60.1", "go.r59.1"},
+		{"release.r61", "go.r61"},
+		{"release.r66", "go.r61.1"},
+		{"weekly.2010-01-01", ""},
+		{"weekly.2010-01-02", "go.weekly.2010-01-02"},
+		{"weekly.2010-01-02.1", "go.weekly.2010-01-02"},
+		{"weekly.2010-01-03", "go.weekly.2010-01-02"},
+		{"weekly.2011-10-12", "go.weekly.2011-10-12"},
+		{"weekly.2011-10-12.1", "go.weekly.2011-10-12.1"},
+		{"weekly.2011-10-13", "go.weekly.2011-10-12.1"},
+		{"weekly.2011-10-14", "go.weekly.2011-10-14"},
+		{"weekly.2011-10-14.1", "go.weekly.2011-10-14"},
+		{"weekly.2011-11-01", "go.weekly.2011-11-01"},
+		{"weekly.2014-01-01", "go.weekly.2011-11-01"},
+		{"weekly.3000-01-01", "go.weekly.2011-11-01"},
+		{"go1", "go1"},
+		{"go1.1", "go1.0.1"},
+		{"go1.998", "go1.9.2"},
+		{"go1.1000", "go1.999"},
+		{"go6", "go5"},
+
+		// faulty versions:
+		{"release.f00", ""},
+		{"weekly.1999-01-01", ""},
+		{"junk", ""},
+		{"", ""},
+		{"go2x", ""},
+		{"go200000000000", ""},
+		{"go2.", ""},
+		{"go2.0", ""},
+	*/
+	{"anything", "go1"},
+}
+
+func TestSelectTag(t *testing.T) {
+	for _, c := range selectTagTests {
+		selected := selectTag(c.version, selectTagTestTags)
+		if selected != c.selected {
+			t.Errorf("selectTag(%q) = %q, want %q", c.version, selected, c.selected)
+		}
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/test.bash b/third_party/gofrontend/libgo/go/cmd/go/test.bash
new file mode 100755
index 0000000..0060ce2
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/test.bash
@@ -0,0 +1,820 @@
+#!/bin/bash
+# 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.
+
+set -e
+go build -o testgo
+go() {
+	echo TEST ERROR: ran go, not testgo: go "$@" >&2
+	exit 2
+}
+
+started=false
+TEST() {
+	if $started; then
+		stop
+	fi
+	echo TEST: "$@"
+	started=true
+	ok=true
+}
+stop() {
+	if ! $started; then
+		echo TEST ERROR: stop missing start >&2
+		exit 2
+	fi
+	started=false
+	if $ok; then
+		echo PASS
+	else
+		echo FAIL
+		allok=false
+	fi
+}
+
+ok=true
+allok=true
+
+unset GOBIN
+unset GOPATH
+unset GOROOT
+
+TEST 'file:line in error messages'
+# Test that error messages have file:line information at beginning of
+# the line. Also test issue 4917: that the error is on stderr.
+d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
+fn=$d/err.go
+echo "package main" > $fn
+echo 'import "bar"' >> $fn
+./testgo run $fn 2>$d/err.out || true
+if ! grep -q "^$fn:" $d/err.out; then
+	echo "missing file:line in error message"
+	cat $d/err.out
+	ok=false
+fi
+rm -r $d
+
+# Test local (./) imports.
+testlocal() {
+	local="$1"
+	TEST local imports $2 '(easy)'
+	./testgo build -o hello "testdata/$local/easy.go"
+	./hello >hello.out
+	if ! grep -q '^easysub\.Hello' hello.out; then
+		echo "testdata/$local/easy.go did not generate expected output"
+		cat hello.out
+		ok=false
+	fi
+	
+	TEST local imports $2 '(easysub)'
+	./testgo build -o hello "testdata/$local/easysub/main.go"
+	./hello >hello.out
+	if ! grep -q '^easysub\.Hello' hello.out; then
+		echo "testdata/$local/easysub/main.go did not generate expected output"
+		cat hello.out
+		ok=false
+	fi
+	
+	TEST local imports $2 '(hard)'
+	./testgo build -o hello "testdata/$local/hard.go"
+	./hello >hello.out
+	if ! grep -q '^sub\.Hello' hello.out || ! grep -q '^subsub\.Hello' hello.out ; then
+		echo "testdata/$local/hard.go did not generate expected output"
+		cat hello.out
+		ok=false
+	fi
+	
+	rm -f hello.out hello
+	
+	# Test that go install x.go fails.
+	TEST local imports $2 '(go install should fail)'
+	if ./testgo install "testdata/$local/easy.go" >/dev/null 2>&1; then
+		echo "go install testdata/$local/easy.go succeeded"
+		ok=false
+	fi
+}
+
+# Test local imports
+testlocal local ''
+
+# Test local imports again, with bad characters in the directory name.
+bad='#$%:, &()*;<=>?\^{}'
+rm -rf "testdata/$bad"
+cp -R testdata/local "testdata/$bad"
+testlocal "$bad" 'with bad characters in path'
+rm -rf "testdata/$bad"
+
+TEST error message for syntax error in test go file says FAIL
+export GOPATH=$(pwd)/testdata
+if ./testgo test syntaxerror 2>testdata/err; then
+	echo 'go test syntaxerror succeeded'
+	ok=false
+elif ! grep FAIL testdata/err >/dev/null; then
+	echo 'go test did not say FAIL:'
+	cat testdata/err
+	ok=false
+fi
+rm -f ./testdata/err
+unset GOPATH
+
+TEST wildcards do not look in useless directories
+export GOPATH=$(pwd)/testdata
+if ./testgo list ... >testdata/err 2>&1; then
+	echo "go list ... succeeded"
+	ok=false
+elif ! grep badpkg testdata/err >/dev/null; then
+	echo "go list ... failure does not mention badpkg"
+	cat testdata/err
+	ok=false
+elif ! ./testgo list m... >testdata/err 2>&1; then
+	echo "go list m... failed"
+	ok=false
+fi
+rm -rf ./testdata/err
+unset GOPATH
+
+# Test tests with relative imports.
+TEST relative imports '(go test)'
+if ! ./testgo test ./testdata/testimport; then
+	echo "go test ./testdata/testimport failed"
+	ok=false
+fi
+
+# Test installation with relative imports.
+TEST relative imports '(go test -i)'
+if ! ./testgo test -i ./testdata/testimport; then
+    echo "go test -i ./testdata/testimport failed"
+    ok=false
+fi
+
+# Test tests with relative imports in packages synthesized
+# from Go files named on the command line.
+TEST relative imports in command-line package
+if ! ./testgo test ./testdata/testimport/*.go; then
+	echo "go test ./testdata/testimport/*.go failed"
+	ok=false
+fi
+
+TEST version control error message includes correct directory
+export GOPATH=$(pwd)/testdata/shadow/root1
+if ./testgo get -u foo 2>testdata/err; then
+	echo "go get -u foo succeeded unexpectedly"
+	ok=false
+elif ! grep testdata/shadow/root1/src/foo testdata/err >/dev/null; then
+	echo "go get -u error does not mention shadow/root1/src/foo:"
+	cat testdata/err
+	ok=false
+fi
+unset GOPATH
+
+TEST go install fails with no buildable files
+export GOPATH=$(pwd)/testdata
+export CGO_ENABLED=0
+if ./testgo install cgotest 2>testdata/err; then
+	echo "go install cgotest succeeded unexpectedly"
+elif ! grep 'no buildable Go source files' testdata/err >/dev/null; then
+	echo "go install cgotest did not report 'no buildable Go source files'"
+	cat testdata/err
+	ok=false
+fi
+unset CGO_ENABLED
+unset GOPATH
+
+# Test that without $GOBIN set, binaries get installed
+# into the GOPATH bin directory.
+TEST install into GOPATH
+rm -rf testdata/bin
+if ! GOPATH=$(pwd)/testdata ./testgo install go-cmd-test; then
+	echo "go install go-cmd-test failed"
+	ok=false
+elif ! test -x testdata/bin/go-cmd-test; then
+	echo "go install go-cmd-test did not write to testdata/bin/go-cmd-test"
+	ok=false
+fi
+
+TEST package main_test imports archive not binary
+export GOBIN=$(pwd)/testdata/bin
+mkdir -p $GOBIN
+export GOPATH=$(pwd)/testdata
+touch ./testdata/src/main_test/m.go
+if ! ./testgo test main_test; then
+	echo "go test main_test failed without install"
+	ok=false
+elif ! ./testgo install main_test; then
+	echo "go test main_test failed"
+	ok=false
+elif [ "$(./testgo list -f '{{.Stale}}' main_test)" != false ]; then
+	echo "after go install, main listed as stale"
+	ok=false
+elif ! ./testgo test main_test; then
+	echo "go test main_test failed after install"
+	ok=false
+fi
+rm -rf $GOBIN
+unset GOBIN
+
+# And with $GOBIN set, binaries get installed to $GOBIN.
+TEST install into GOBIN
+if ! GOBIN=$(pwd)/testdata/bin1 GOPATH=$(pwd)/testdata ./testgo install go-cmd-test; then
+	echo "go install go-cmd-test failed"
+	ok=false
+elif ! test -x testdata/bin1/go-cmd-test; then
+	echo "go install go-cmd-test did not write to testdata/bin1/go-cmd-test"
+	ok=false
+fi
+
+# Without $GOBIN set, installing a program outside $GOPATH should fail
+# (there is nowhere to install it).
+TEST install without destination fails
+if ./testgo install testdata/src/go-cmd-test/helloworld.go 2>testdata/err; then
+	echo "go install testdata/src/go-cmd-test/helloworld.go should have failed, did not"
+	ok=false
+elif ! grep 'no install location for .go files listed on command line' testdata/err; then
+	echo "wrong error:"
+	cat testdata/err
+	ok=false
+fi
+rm -f testdata/err
+
+# With $GOBIN set, should install there.
+TEST install to GOBIN '(command-line package)'
+if ! GOBIN=$(pwd)/testdata/bin1 ./testgo install testdata/src/go-cmd-test/helloworld.go; then
+	echo "go install testdata/src/go-cmd-test/helloworld.go failed"
+	ok=false
+elif ! test -x testdata/bin1/helloworld; then
+	echo "go install testdata/src/go-cmd-test/helloworld.go did not write testdata/bin1/helloworld"
+	ok=false
+fi
+
+TEST godoc installs into GOBIN
+d=$(mktemp -d -t testgoXXX)
+export GOPATH=$d
+mkdir $d/gobin
+GOBIN=$d/gobin ./testgo get code.google.com/p/go.tools/cmd/godoc
+if [ ! -x $d/gobin/godoc ]; then
+	echo did not install godoc to '$GOBIN'
+	GOBIN=$d/gobin ./testgo list -f 'Target: {{.Target}}' code.google.com/p/go.tools/cmd/godoc
+	ok=false
+fi
+
+TEST godoc installs into GOROOT
+GOROOT=$(./testgo env GOROOT)
+rm -f $GOROOT/bin/godoc
+./testgo install code.google.com/p/go.tools/cmd/godoc
+if [ ! -x $GOROOT/bin/godoc ]; then
+	echo did not install godoc to '$GOROOT/bin'
+	./testgo list -f 'Target: {{.Target}}' code.google.com/p/go.tools/cmd/godoc
+	ok=false
+fi
+
+TEST cmd/fix installs into tool
+GOOS=$(./testgo env GOOS)
+GOARCH=$(./testgo env GOARCH)
+rm -f $GOROOT/pkg/tool/${GOOS}_${GOARCH}/fix
+./testgo install cmd/fix
+if [ ! -x $GOROOT/pkg/tool/${GOOS}_${GOARCH}/fix ]; then
+	echo 'did not install cmd/fix to $GOROOT/pkg/tool'
+	GOBIN=$d/gobin ./testgo list -f 'Target: {{.Target}}' cmd/fix
+	ok=false
+fi
+rm -f $GOROOT/pkg/tool/${GOOS}_${GOARCH}/fix
+GOBIN=$d/gobin ./testgo install cmd/fix
+if [ ! -x $GOROOT/pkg/tool/${GOOS}_${GOARCH}/fix ]; then
+	echo 'did not install cmd/fix to $GOROOT/pkg/tool with $GOBIN set'
+	GOBIN=$d/gobin ./testgo list -f 'Target: {{.Target}}' cmd/fix
+	ok=false
+fi
+
+TEST gopath program installs into GOBIN
+mkdir $d/src/progname
+echo 'package main; func main() {}' >$d/src/progname/p.go
+GOBIN=$d/gobin ./testgo install progname
+if [ ! -x $d/gobin/progname ]; then
+	echo 'did not install progname to $GOBIN/progname'
+	./testgo list -f 'Target: {{.Target}}' cmd/api
+	ok=false
+fi
+rm -f $d/gobin/progname $d/bin/progname
+
+TEST gopath program installs into GOPATH/bin
+./testgo install progname
+if [ ! -x $d/bin/progname ]; then
+	echo 'did not install progname to $GOPATH/bin/progname'
+	./testgo list -f 'Target: {{.Target}}' progname
+	ok=false
+fi
+
+unset GOPATH
+rm -rf $d
+
+# Reject relative paths in GOPATH.
+TEST reject relative paths in GOPATH '(command-line package)'
+if GOPATH=. ./testgo build testdata/src/go-cmd-test/helloworld.go; then
+    echo 'GOPATH="." go build should have failed, did not'
+    ok=false
+fi
+
+TEST reject relative paths in GOPATH 
+if GOPATH=:$(pwd)/testdata:. ./testgo build go-cmd-test; then
+    echo 'GOPATH=":$(pwd)/testdata:." go build should have failed, did not'
+    ok=false
+fi
+
+# issue 4104
+TEST go test with package listed multiple times
+if [ $(./testgo test fmt fmt fmt fmt fmt | wc -l) -ne 1 ] ; then
+    echo 'go test fmt fmt fmt fmt fmt tested the same package multiple times'
+    ok=false
+fi
+
+# ensure that output of 'go list' is consistent between runs
+TEST go list is consistent
+./testgo list std > test_std.list
+if ! ./testgo list std | cmp -s test_std.list - ; then
+	echo "go list std ordering is inconsistent"
+	ok=false
+fi
+rm -f test_std.list
+
+# issue 4096. Validate the output of unsuccessful go install foo/quxx 
+TEST unsuccessful go install should mention missing package
+if [ $(./testgo install 'foo/quxx' 2>&1 | grep -c 'cannot find package "foo/quxx" in any of') -ne 1 ] ; then
+	echo 'go install foo/quxx expected error: .*cannot find package "foo/quxx" in any of'
+	ok=false
+fi 
+# test GOROOT search failure is reported
+TEST GOROOT search failure reporting
+if [ $(./testgo install 'foo/quxx' 2>&1 | egrep -c 'foo/quxx \(from \$GOROOT\)$') -ne 1 ] ; then
+        echo 'go install foo/quxx expected error: .*foo/quxx (from $GOROOT)'
+        ok=false
+fi
+# test multiple GOPATH entries are reported separately
+TEST multiple GOPATH entries reported separately
+if [ $(GOPATH=$(pwd)/testdata/a:$(pwd)/testdata/b ./testgo install 'foo/quxx' 2>&1 | egrep -c 'testdata/./src/foo/quxx') -ne 2 ] ; then
+        echo 'go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)\n.*testdata/b/src/foo/quxx'
+        ok=false
+fi
+# test (from $GOPATH) annotation is reported for the first GOPATH entry
+TEST mention GOPATH in first GOPATH entry
+if [ $(GOPATH=$(pwd)/testdata/a:$(pwd)/testdata/b ./testgo install 'foo/quxx' 2>&1 | egrep -c 'testdata/a/src/foo/quxx \(from \$GOPATH\)$') -ne 1 ] ; then
+        echo 'go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)'
+        ok=false
+fi
+# but not on the second
+TEST but not the second entry
+if [ $(GOPATH=$(pwd)/testdata/a:$(pwd)/testdata/b ./testgo install 'foo/quxx' 2>&1 | egrep -c 'testdata/b/src/foo/quxx$') -ne 1 ] ; then
+        echo 'go install foo/quxx expected error: .*testdata/b/src/foo/quxx'
+        ok=false
+fi
+# test missing GOPATH is reported
+TEST missing GOPATH is reported
+if [ $(GOPATH= ./testgo install 'foo/quxx' 2>&1 | egrep -c '\(\$GOPATH not set\)$') -ne 1 ] ; then
+        echo 'go install foo/quxx expected error: ($GOPATH not set)'
+        ok=false
+fi
+
+# issue 4186. go get cannot be used to download packages to $GOROOT
+# Test that without GOPATH set, go get should fail
+TEST without GOPATH, go get fails
+d=$(mktemp -d -t testgoXXX)
+mkdir -p $d/src/pkg
+if GOPATH= GOROOT=$d ./testgo get -d code.google.com/p/go.codereview/cmd/hgpatch ; then 
+	echo 'go get code.google.com/p/go.codereview/cmd/hgpatch should not succeed with $GOPATH unset'
+	ok=false
+fi	
+rm -rf $d
+
+# Test that with GOPATH=$GOROOT, go get should fail
+TEST with GOPATH=GOROOT, go get fails
+d=$(mktemp -d -t testgoXXX)
+mkdir -p $d/src/pkg
+if GOPATH=$d GOROOT=$d ./testgo get -d code.google.com/p/go.codereview/cmd/hgpatch ; then
+        echo 'go get code.google.com/p/go.codereview/cmd/hgpatch should not succeed with GOPATH=$GOROOT'
+        ok=false
+fi
+rm -rf $d
+
+TEST ldflags arguments with spaces '(issue 3941)'
+d=$(mktemp -d -t testgoXXX)
+cat >$d/main.go<<EOF
+package main
+var extern string
+func main() {
+	println(extern)
+}
+EOF
+./testgo run -ldflags '-X main.extern "hello world"' $d/main.go 2>hello.out
+if ! grep -q '^hello world' hello.out; then
+	echo "ldflags -X main.extern 'hello world' failed. Output:"
+	cat hello.out
+	ok=false
+fi
+rm -rf $d hello.out
+
+TEST go test -cpuprofile leaves binary behind
+./testgo test -cpuprofile strings.prof strings || ok=false
+if [ ! -x strings.test ]; then
+	echo "go test -cpuprofile did not create strings.test"
+	ok=false
+fi
+rm -f strings.prof strings.test
+
+TEST symlinks do not confuse go list '(issue 4568)'
+old=$(pwd)
+tmp=$(cd /tmp && pwd -P)
+d=$(TMPDIR=$tmp mktemp -d -t testgoXXX)
+mkdir -p $d/src
+(
+	ln -s $d $d/src/dir1
+	cd $d/src
+	echo package p >dir1/p.go
+	export GOPATH=$d
+	if [ "$($old/testgo list -f '{{.Root}}' dir1)" != "$d" ]; then
+		echo Confused by symlinks.
+		echo "Package in current directory $(pwd) should have Root $d"
+		env|grep WD
+		$old/testgo list -json . dir1
+		touch $d/failed
+	fi		
+)
+if [ -f $d/failed ]; then
+	ok=false
+fi
+rm -rf $d
+
+TEST 'install with tags (issue 4515)'
+d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
+mkdir -p $d/src/example/a $d/src/example/b $d/bin
+cat >$d/src/example/a/main.go <<EOF
+package main
+func main() {}
+EOF
+cat >$d/src/example/b/main.go <<EOF
+// +build mytag
+
+package main
+func main() {}
+EOF
+GOPATH=$d ./testgo install -tags mytag example/a example/b || ok=false
+if [ ! -x $d/bin/a -o ! -x $d/bin/b ]; then
+	echo go install example/a example/b did not install binaries
+	ok=false
+fi
+rm -f $d/bin/*
+GOPATH=$d ./testgo install -tags mytag example/... || ok=false
+if [ ! -x $d/bin/a -o ! -x $d/bin/b ]; then
+	echo go install example/... did not install binaries
+	ok=false
+fi
+rm -f $d/bin/*go
+export GOPATH=$d
+if [ "$(./testgo list -tags mytag example/b...)" != "example/b" ]; then
+	echo go list example/b did not find example/b
+	ok=false
+fi
+unset GOPATH
+rm -rf $d
+
+TEST case collisions '(issue 4773)'
+d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
+export GOPATH=$d
+mkdir -p $d/src/example/{a/pkg,a/Pkg,b}
+cat >$d/src/example/a/a.go <<EOF
+package p
+import (
+	_ "example/a/pkg"
+	_ "example/a/Pkg"
+)
+EOF
+cat >$d/src/example/a/pkg/pkg.go <<EOF
+package pkg
+EOF
+cat >$d/src/example/a/Pkg/pkg.go <<EOF
+package pkg
+EOF
+if ./testgo list example/a 2>$d/out; then
+	echo go list example/a should have failed, did not.
+	ok=false
+elif ! grep "case-insensitive import collision" $d/out >/dev/null; then
+	echo go list example/a did not report import collision.
+	ok=false
+fi
+cat >$d/src/example/b/file.go <<EOF
+package b
+EOF
+cat >$d/src/example/b/FILE.go <<EOF
+package b
+EOF
+if [ $(ls $d/src/example/b | wc -l) = 2 ]; then
+	# case-sensitive file system, let directory read find both files
+	args="example/b"
+else
+	# case-insensitive file system, list files explicitly on command line.
+	args="$d/src/example/b/file.go $d/src/example/b/FILE.go"
+fi
+if ./testgo list $args 2>$d/out; then
+	echo go list example/b should have failed, did not.
+	ok=false
+elif ! grep "case-insensitive file name collision" $d/out >/dev/null; then
+	echo go list example/b did not report file name collision.
+	ok=false
+fi
+
+TEST go get cover
+./testgo get code.google.com/p/go.tools/cmd/cover || ok=false
+
+unset GOPATH
+rm -rf $d
+
+TEST shadowing logic
+export GOPATH=$(pwd)/testdata/shadow/root1:$(pwd)/testdata/shadow/root2
+
+# The math in root1 is not "math" because the standard math is.
+cdir=$(./testgo list -f '({{.ImportPath}}) ({{.ConflictDir}})' ./testdata/shadow/root1/src/math)
+if [ "$cdir" != "(_$(pwd)/testdata/shadow/root1/src/math) ($GOROOT/src/pkg/math)" ]; then
+	echo shadowed math is not shadowed: "$cdir"
+	ok=false
+fi
+
+# The foo in root1 is "foo".
+cdir=$(./testgo list -f '({{.ImportPath}}) ({{.ConflictDir}})' ./testdata/shadow/root1/src/foo)
+if [ "$cdir" != "(foo) ()" ]; then
+	echo unshadowed foo is shadowed: "$cdir"
+	ok=false
+fi
+
+# The foo in root2 is not "foo" because the foo in root1 got there first.
+cdir=$(./testgo list -f '({{.ImportPath}}) ({{.ConflictDir}})' ./testdata/shadow/root2/src/foo)
+if [ "$cdir" != "(_$(pwd)/testdata/shadow/root2/src/foo) ($(pwd)/testdata/shadow/root1/src/foo)" ]; then
+	echo shadowed foo is not shadowed: "$cdir"
+	ok=false
+fi
+
+# The error for go install should mention the conflicting directory.
+err=$(! ./testgo install ./testdata/shadow/root2/src/foo 2>&1)
+if [ "$err" != "go install: no install location for $(pwd)/testdata/shadow/root2/src/foo: hidden by $(pwd)/testdata/shadow/root1/src/foo" ]; then
+	echo wrong shadowed install error: "$err"
+	ok=false
+fi
+
+# Only succeeds if source order is preserved.
+TEST source file name order preserved
+./testgo test testdata/example[12]_test.go || ok=false
+
+# Check that coverage analysis works at all.
+# Don't worry about the exact numbers but require not 0.0%.
+checkcoverage() {
+	if grep '[^0-9]0\.0%' testdata/cover.txt >/dev/null; then
+		echo 'some coverage results are 0.0%'
+		ok=false
+	fi
+	cat testdata/cover.txt
+	rm -f testdata/cover.txt
+}
+	
+TEST coverage runs
+./testgo test -short -coverpkg=strings strings regexp >testdata/cover.txt 2>&1 || ok=false
+./testgo test -short -cover strings math regexp >>testdata/cover.txt 2>&1 || ok=false
+checkcoverage
+
+# Check that coverage analysis uses set mode.
+TEST coverage uses set mode
+if ./testgo test -short -cover encoding/binary -coverprofile=testdata/cover.out >testdata/cover.txt 2>&1; then
+	if ! grep -q 'mode: set' testdata/cover.out; then
+		ok=false
+	fi
+	checkcoverage
+else
+	ok=false
+fi
+rm -f testdata/cover.out testdata/cover.txt
+
+TEST coverage uses atomic mode for -race.
+if ./testgo test -short -race -cover encoding/binary -coverprofile=testdata/cover.out >testdata/cover.txt 2>&1; then
+	if ! grep -q 'mode: atomic' testdata/cover.out; then
+		ok=false
+	fi
+	checkcoverage
+else
+	ok=false
+fi
+rm -f testdata/cover.out
+
+TEST coverage uses actual setting to override even for -race.
+if ./testgo test -short -race -cover encoding/binary -covermode=count -coverprofile=testdata/cover.out >testdata/cover.txt 2>&1; then
+	if ! grep -q 'mode: count' testdata/cover.out; then
+		ok=false
+	fi
+	checkcoverage
+else
+	ok=false
+fi
+rm -f testdata/cover.out
+
+TEST coverage with cgo
+d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
+./testgo test -short -cover ./testdata/cgocover >testdata/cover.txt 2>&1 || ok=false
+checkcoverage
+
+TEST cgo depends on syscall
+rm -rf $GOROOT/pkg/*_race
+d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
+export GOPATH=$d
+mkdir -p $d/src/foo
+echo '
+package foo
+//#include <stdio.h>
+import "C"
+' >$d/src/foo/foo.go
+./testgo build -race foo || ok=false
+rm -rf $d
+unset GOPATH
+
+TEST cgo shows full path names
+d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
+export GOPATH=$d
+mkdir -p $d/src/x/y/dirname
+echo '
+package foo
+import "C"
+func f() {
+' >$d/src/x/y/dirname/foo.go
+if ./testgo build x/y/dirname >$d/err 2>&1; then
+	echo build succeeded unexpectedly.
+	ok=false
+elif ! grep x/y/dirname $d/err >/dev/null; then
+	echo error did not use full path.
+	cat $d/err
+	ok=false
+fi
+rm -rf $d
+unset GOPATH
+
+TEST 'cgo handles -Wl,$ORIGIN'
+d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
+export GOPATH=$d
+mkdir -p $d/src/origin
+echo '
+package origin
+// #cgo !darwin LDFLAGS: -Wl,-rpath -Wl,$ORIGIN
+// void f(void) {}
+import "C"
+
+func f() { C.f() }
+' >$d/src/origin/origin.go
+if ! ./testgo build origin; then
+	echo build failed
+	ok=false
+fi
+rm -rf $d
+unset GOPATH
+
+TEST 'Issue 6480: "go test -c -test.bench=XXX fmt" should not hang'
+if ! ./testgo test -c -test.bench=XXX fmt; then
+	echo build test failed
+	ok=false
+fi
+rm -f fmt.test
+
+TEST 'Issue 7573: cmd/cgo: undefined reference when linking a C-library using gccgo'
+d=$(mktemp -d -t testgoXXX)
+export GOPATH=$d
+mkdir -p $d/src/cgoref
+ldflags="-L alibpath -lalib"
+echo "
+package main
+// #cgo LDFLAGS: $ldflags
+// void f(void) {}
+import \"C\"
+
+func main() { C.f() }
+" >$d/src/cgoref/cgoref.go
+go_cmds="$(./testgo build -n -compiler gccgo cgoref 2>&1 1>/dev/null)"
+ldflags_count="$(echo "$go_cmds" | egrep -c "^gccgo.*$(echo $ldflags | sed -e 's/-/\\-/g')" || true)"
+if [ "$ldflags_count" -lt 1 ]; then
+	echo "No Go-inline "#cgo LDFLAGS:" (\"$ldflags\") passed to gccgo linking stage."
+	ok=false
+fi
+rm -rf $d
+unset ldflags_count
+unset go_cmds
+unset ldflags
+unset GOPATH
+
+TEST list template can use context function
+if ! ./testgo list -f "GOARCH: {{context.GOARCH}}"; then 
+	echo unable to use context in list template
+	ok=false
+fi
+
+TEST 'Issue 7108: cmd/go: "go test" should fail if package does not build'
+export GOPATH=$(pwd)/testdata
+if ./testgo test notest >/dev/null 2>&1; then
+	echo 'go test notest succeeded, but should fail'
+	ok=false
+fi
+unset GOPATH
+
+TEST 'Issue 6844: cmd/go: go test -a foo does not rebuild regexp'
+if ! ./testgo test -x -a -c testdata/dep_test.go 2>deplist; then
+	echo "go test -x -a -c testdata/dep_test.go failed"
+	ok=false
+elif ! grep -q regexp deplist; then
+	echo "go test -x -a -c testdata/dep_test.go did not rebuild regexp"
+	ok=false
+fi
+rm -f deplist
+rm -f deps.test
+
+TEST list template can use context function
+if ! ./testgo list -f "GOARCH: {{context.GOARCH}}"; then 
+	echo unable to use context in list template
+	ok=false
+fi
+
+TEST build -i installs dependencies
+d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
+export GOPATH=$d
+mkdir -p $d/src/x/y/foo $d/src/x/y/bar
+echo '
+package foo
+func F() {}
+' >$d/src/x/y/foo/foo.go
+echo '
+package bar
+import "x/y/foo"
+func F() { foo.F() }
+' >$d/src/x/y/bar/bar.go
+if ! ./testgo build -v -i x/y/bar &> $d/err; then
+	echo build -i failed
+	cat $d/err
+	ok=false
+elif ! grep x/y/foo $d/err >/dev/null; then
+	echo first build -i did not build x/y/foo
+	cat $d/err
+	ok=false
+fi
+if ! ./testgo build -v -i x/y/bar &> $d/err; then
+	echo second build -i failed
+	cat $d/err
+	ok=false
+elif grep x/y/foo $d/err >/dev/null; then
+	echo second build -i built x/y/foo
+	cat $d/err
+	ok=false
+fi
+rm -rf $d
+unset GOPATH
+
+TEST 'go build in test-only directory fails with a good error'
+if ./testgo build ./testdata/testonly 2>testdata/err.out; then
+	echo "go build ./testdata/testonly succeeded, should have failed"
+	ok=false
+elif ! grep 'no buildable Go' testdata/err.out >/dev/null; then
+	echo "go build ./testdata/testonly produced unexpected error:"
+	cat testdata/err.out
+	ok=false
+fi
+rm -f testdata/err.out
+
+TEST 'go test detects test-only import cycles'
+export GOPATH=$(pwd)/testdata
+if ./testgo test -c testcycle/p3 2>testdata/err.out; then
+	echo "go test testcycle/p3 succeeded, should have failed"
+	ok=false
+elif ! grep 'import cycle not allowed in test' testdata/err.out >/dev/null; then
+	echo "go test testcycle/p3 produced unexpected error:"
+	cat testdata/err.out
+	ok=false
+fi
+rm -f testdata/err.out
+unset GOPATH
+
+TEST 'go test foo_test.go works'
+if ! ./testgo test testdata/standalone_test.go; then
+	echo "go test testdata/standalone_test.go failed"
+	ok=false
+fi
+
+TEST 'go test xtestonly works'
+export GOPATH=$(pwd)/testdata
+./testgo clean -i xtestonly
+if ! ./testgo test xtestonly >/dev/null; then
+	echo "go test xtestonly failed"
+	ok=false
+fi
+unset GOPATH
+
+
+# clean up
+if $started; then stop; fi
+rm -rf testdata/bin testdata/bin1
+rm -f testgo
+
+if $allok; then
+	echo PASS
+else
+	echo FAIL
+	exit 1
+fi
diff --git a/third_party/gofrontend/libgo/go/cmd/go/test.go b/third_party/gofrontend/libgo/go/cmd/go/test.go
new file mode 100644
index 0000000..f7ae9c0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/test.go
@@ -0,0 +1,1308 @@
+// Copyright 2011 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 (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/build"
+	"go/doc"
+	"go/parser"
+	"go/token"
+	"log"
+	"os"
+	"os/exec"
+	"path"
+	"path/filepath"
+	"regexp"
+	"runtime"
+	"sort"
+	"strings"
+	"text/template"
+	"time"
+	"unicode"
+	"unicode/utf8"
+)
+
+// Break init loop.
+func init() {
+	cmdTest.Run = runTest
+}
+
+var cmdTest = &Command{
+	CustomFlags: true,
+	UsageLine:   "test [-c] [-i] [build and test flags] [packages] [flags for test binary]",
+	Short:       "test packages",
+	Long: `
+'Go test' automates testing the packages named by the import paths.
+It prints a summary of the test results in the format:
+
+	ok   archive/tar   0.011s
+	FAIL archive/zip   0.022s
+	ok   compress/gzip 0.033s
+	...
+
+followed by detailed output for each failed package.
+
+'Go test' recompiles each package along with any files with names matching
+the file pattern "*_test.go". 
+Files whose names begin with "_" (including "_test.go") or "." are ignored.
+These additional files can contain test functions, benchmark functions, and
+example functions.  See 'go help testfunc' for more.
+Each listed package causes the execution of a separate test binary.
+
+Test files that declare a package with the suffix "_test" will be compiled as a
+separate package, and then linked and run with the main test binary.
+
+By default, go test needs no arguments.  It compiles and tests the package
+with source in the current directory, including tests, and runs the tests.
+
+The package is built in a temporary directory so it does not interfere with the
+non-test installation.
+
+In addition to the build flags, the flags handled by 'go test' itself are:
+
+	-c  Compile the test binary to pkg.test but do not run it.
+	    (Where pkg is the last element of the package's import path.)
+
+	-i
+	    Install packages that are dependencies of the test.
+	    Do not run the test.
+
+	-exec xprog
+	    Run the test binary using xprog. The behavior is the same as
+	    in 'go run'. See 'go help run' for details.
+
+The test binary also accepts flags that control execution of the test; these
+flags are also accessible by 'go test'.  See 'go help testflag' for details.
+
+If the test binary needs any other flags, they should be presented after the
+package names. The go tool treats as a flag the first argument that begins with
+a minus sign that it does not recognize itself; that argument and all subsequent
+arguments are passed as arguments to the test binary.
+
+For more about build flags, see 'go help build'.
+For more about specifying packages, see 'go help packages'.
+
+See also: go build, go vet.
+`,
+}
+
+var helpTestflag = &Command{
+	UsageLine: "testflag",
+	Short:     "description of testing flags",
+	Long: `
+The 'go test' command takes both flags that apply to 'go test' itself
+and flags that apply to the resulting test binary.
+
+Several of the flags control profiling and write an execution profile
+suitable for "go tool pprof"; run "go tool pprof help" for more
+information.  The --alloc_space, --alloc_objects, and --show_bytes
+options of pprof control how the information is presented.
+
+The following flags are recognized by the 'go test' command and
+control the execution of any test:
+
+	-bench regexp
+	    Run benchmarks matching the regular expression.
+	    By default, no benchmarks run. To run all benchmarks,
+	    use '-bench .' or '-bench=.'.
+
+	-benchmem
+	    Print memory allocation statistics for benchmarks.
+
+	-benchtime t
+	    Run enough iterations of each benchmark to take t, specified
+	    as a time.Duration (for example, -benchtime 1h30s).
+	    The default is 1 second (1s).
+
+	-blockprofile block.out
+	    Write a goroutine blocking profile to the specified file
+	    when all tests are complete.
+
+	-blockprofilerate n
+	    Control the detail provided in goroutine blocking profiles by
+	    calling runtime.SetBlockProfileRate with n.
+	    See 'godoc runtime SetBlockProfileRate'.
+	    The profiler aims to sample, on average, one blocking event every
+	    n nanoseconds the program spends blocked.  By default,
+	    if -test.blockprofile is set without this flag, all blocking events
+	    are recorded, equivalent to -test.blockprofilerate=1.
+
+	-cover
+	    Enable coverage analysis.
+
+	-covermode set,count,atomic
+	    Set the mode for coverage analysis for the package[s]
+	    being tested. The default is "set" unless -race is enabled,
+	    in which case it is "atomic".
+	    The values:
+		set: bool: does this statement run?
+		count: int: how many times does this statement run?
+		atomic: int: count, but correct in multithreaded tests;
+			significantly more expensive.
+	    Sets -cover.
+
+	-coverpkg pkg1,pkg2,pkg3
+	    Apply coverage analysis in each test to the given list of packages.
+	    The default is for each test to analyze only the package being tested.
+	    Packages are specified as import paths.
+	    Sets -cover.
+
+	-coverprofile cover.out
+	    Write a coverage profile to the specified file after all tests
+	    have passed.
+	    Sets -cover.
+
+	-cpu 1,2,4
+	    Specify a list of GOMAXPROCS values for which the tests or
+	    benchmarks should be executed.  The default is the current value
+	    of GOMAXPROCS.
+
+	-cpuprofile cpu.out
+	    Write a CPU profile to the specified file before exiting.
+
+	-memprofile mem.out
+	    Write a memory profile to the specified file after all tests
+	    have passed.
+
+	-memprofilerate n
+	    Enable more precise (and expensive) memory profiles by setting
+	    runtime.MemProfileRate.  See 'godoc runtime MemProfileRate'.
+	    To profile all memory allocations, use -test.memprofilerate=1
+	    and pass --alloc_space flag to the pprof tool.
+
+	-outputdir directory
+	    Place output files from profiling in the specified directory,
+	    by default the directory in which "go test" is running.
+
+	-parallel n
+	    Allow parallel execution of test functions that call t.Parallel.
+	    The value of this flag is the maximum number of tests to run
+	    simultaneously; by default, it is set to the value of GOMAXPROCS.
+
+	-run regexp
+	    Run only those tests and examples matching the regular
+	    expression.
+
+	-short
+	    Tell long-running tests to shorten their run time.
+	    It is off by default but set during all.bash so that installing
+	    the Go tree can run a sanity check but not spend time running
+	    exhaustive tests.
+
+	-timeout t
+	    If a test runs longer than t, panic.
+
+	-v
+	    Verbose output: log all tests as they are run. Also print all
+	    text from Log and Logf calls even if the test succeeds.
+
+The test binary, called pkg.test where pkg is the name of the
+directory containing the package sources, can be invoked directly
+after building it with 'go test -c'. When invoking the test binary
+directly, each of the standard flag names must be prefixed with 'test.',
+as in -test.run=TestMyFunc or -test.v.
+
+When running 'go test', flags not listed above are passed through
+unaltered. For instance, the command
+
+	go test -x -v -cpuprofile=prof.out -dir=testdata -update
+
+will compile the test binary and then run it as
+
+	pkg.test -test.v -test.cpuprofile=prof.out -dir=testdata -update
+
+The test flags that generate profiles (other than for coverage) also
+leave the test binary in pkg.test for use when analyzing the profiles.
+
+Flags not recognized by 'go test' must be placed after any specified packages.
+`,
+}
+
+var helpTestfunc = &Command{
+	UsageLine: "testfunc",
+	Short:     "description of testing functions",
+	Long: `
+The 'go test' command expects to find test, benchmark, and example functions
+in the "*_test.go" files corresponding to the package under test.
+
+A test function is one named TestXXX (where XXX is any alphanumeric string
+not starting with a lower case letter) and should have the signature,
+
+	func TestXXX(t *testing.T) { ... }
+
+A benchmark function is one named BenchmarkXXX and should have the signature,
+
+	func BenchmarkXXX(b *testing.B) { ... }
+
+An example function is similar to a test function but, instead of using
+*testing.T to report success or failure, prints output to os.Stdout.
+That output is compared against the function's "Output:" comment, which
+must be the last comment in the function body (see example below). An
+example with no such comment, or with no text after "Output:" is compiled
+but not executed.
+
+Godoc displays the body of ExampleXXX to demonstrate the use
+of the function, constant, or variable XXX.  An example of a method M with
+receiver type T or *T is named ExampleT_M.  There may be multiple examples
+for a given function, constant, or variable, distinguished by a trailing _xxx,
+where xxx is a suffix not beginning with an upper case letter.
+
+Here is an example of an example:
+
+	func ExamplePrintln() {
+		Println("The output of\nthis example.")
+		// Output: The output of
+		// this example.
+	}
+
+The entire test file is presented as the example when it contains a single
+example function, at least one other function, type, variable, or constant
+declaration, and no test or benchmark functions.
+
+See the documentation of the testing package for more information.
+`,
+}
+
+var (
+	testC            bool       // -c flag
+	testCover        bool       // -cover flag
+	testCoverMode    string     // -covermode flag
+	testCoverPaths   []string   // -coverpkg flag
+	testCoverPkgs    []*Package // -coverpkg flag
+	testProfile      bool       // some profiling flag
+	testNeedBinary   bool       // profile needs to keep binary around
+	testV            bool       // -v flag
+	testFiles        []string   // -file flag(s)  TODO: not respected
+	testTimeout      string     // -timeout flag
+	testArgs         []string
+	testBench        bool
+	testStreamOutput bool // show output as it is generated
+	testShowPass     bool // show passing output
+
+	testKillTimeout = 10 * time.Minute
+)
+
+var testMainDeps = map[string]bool{
+	// Dependencies for testmain.
+	"testing": true,
+	"regexp":  true,
+}
+
+func runTest(cmd *Command, args []string) {
+	var pkgArgs []string
+	pkgArgs, testArgs = testFlags(args)
+
+	findExecCmd() // initialize cached result
+
+	raceInit()
+	pkgs := packagesForBuild(pkgArgs)
+	if len(pkgs) == 0 {
+		fatalf("no packages to test")
+	}
+
+	if testC && len(pkgs) != 1 {
+		fatalf("cannot use -c flag with multiple packages")
+	}
+	if testProfile && len(pkgs) != 1 {
+		fatalf("cannot use test profile flag with multiple packages")
+	}
+
+	// If a test timeout was given and is parseable, set our kill timeout
+	// to that timeout plus one minute.  This is a backup alarm in case
+	// the test wedges with a goroutine spinning and its background
+	// timer does not get a chance to fire.
+	if dt, err := time.ParseDuration(testTimeout); err == nil && dt > 0 {
+		testKillTimeout = dt + 1*time.Minute
+	}
+
+	// show passing test output (after buffering) with -v flag.
+	// must buffer because tests are running in parallel, and
+	// otherwise the output will get mixed.
+	testShowPass = testV
+
+	// stream test output (no buffering) when no package has
+	// been given on the command line (implicit current directory)
+	// or when benchmarking.
+	// Also stream if we're showing output anyway with a
+	// single package under test.  In that case, streaming the
+	// output produces the same result as not streaming,
+	// just more immediately.
+	testStreamOutput = len(pkgArgs) == 0 || testBench ||
+		(len(pkgs) <= 1 && testShowPass)
+
+	var b builder
+	b.init()
+
+	if buildI {
+		buildV = testV
+
+		deps := make(map[string]bool)
+		for dep := range testMainDeps {
+			deps[dep] = true
+		}
+
+		for _, p := range pkgs {
+			// Dependencies for each test.
+			for _, path := range p.Imports {
+				deps[path] = true
+			}
+			for _, path := range p.TestImports {
+				deps[path] = true
+			}
+			for _, path := range p.XTestImports {
+				deps[path] = true
+			}
+		}
+
+		// translate C to runtime/cgo
+		if deps["C"] {
+			delete(deps, "C")
+			deps["runtime/cgo"] = true
+			if buildContext.GOOS == runtime.GOOS && buildContext.GOARCH == runtime.GOARCH {
+				deps["cmd/cgo"] = true
+			}
+		}
+		// Ignore pseudo-packages.
+		delete(deps, "unsafe")
+
+		all := []string{}
+		if reqPkgSrc {
+			for path := range deps {
+				if !build.IsLocalImport(path) {
+					all = append(all, path)
+				}
+			}
+		}
+		sort.Strings(all)
+
+		a := &action{}
+		for _, p := range packagesForBuild(all) {
+			a.deps = append(a.deps, b.action(modeInstall, modeInstall, p))
+		}
+		b.do(a)
+		if !testC || a.failed {
+			return
+		}
+		b.init()
+	}
+
+	var builds, runs, prints []*action
+
+	if testCoverPaths != nil {
+		// Load packages that were asked about for coverage.
+		// packagesForBuild exits if the packages cannot be loaded.
+		testCoverPkgs = packagesForBuild(testCoverPaths)
+
+		// Warn about -coverpkg arguments that are not actually used.
+		used := make(map[string]bool)
+		for _, p := range pkgs {
+			used[p.ImportPath] = true
+			for _, dep := range p.Deps {
+				used[dep] = true
+			}
+		}
+		for _, p := range testCoverPkgs {
+			if !used[p.ImportPath] {
+				log.Printf("warning: no packages being tested depend on %s", p.ImportPath)
+			}
+		}
+
+		// Mark all the coverage packages for rebuilding with coverage.
+		for _, p := range testCoverPkgs {
+			p.Stale = true // rebuild
+			p.fake = true  // do not warn about rebuild
+			p.coverMode = testCoverMode
+			var coverFiles []string
+			coverFiles = append(coverFiles, p.GoFiles...)
+			coverFiles = append(coverFiles, p.CgoFiles...)
+			coverFiles = append(coverFiles, p.TestGoFiles...)
+			p.coverVars = declareCoverVars(p.ImportPath, coverFiles...)
+		}
+	}
+
+	// Prepare build + run + print actions for all packages being tested.
+	for _, p := range pkgs {
+		buildTest, runTest, printTest, err := b.test(p)
+		if err != nil {
+			str := err.Error()
+			if strings.HasPrefix(str, "\n") {
+				str = str[1:]
+			}
+			failed := fmt.Sprintf("FAIL\t%s [setup failed]\n", p.ImportPath)
+
+			if p.ImportPath != "" {
+				errorf("# %s\n%s\n%s", p.ImportPath, str, failed)
+			} else {
+				errorf("%s\n%s", str, failed)
+			}
+			continue
+		}
+		builds = append(builds, buildTest)
+		runs = append(runs, runTest)
+		prints = append(prints, printTest)
+	}
+
+	// Ultimately the goal is to print the output.
+	root := &action{deps: prints}
+
+	// Force the printing of results to happen in order,
+	// one at a time.
+	for i, a := range prints {
+		if i > 0 {
+			a.deps = append(a.deps, prints[i-1])
+		}
+	}
+
+	// Force benchmarks to run in serial.
+	if !testC && testBench {
+		// The first run must wait for all builds.
+		// Later runs must wait for the previous run's print.
+		for i, run := range runs {
+			if i == 0 {
+				run.deps = append(run.deps, builds...)
+			} else {
+				run.deps = append(run.deps, prints[i-1])
+			}
+		}
+	}
+
+	// If we are building any out-of-date packages other
+	// than those under test, warn.
+	okBuild := map[*Package]bool{}
+	for _, p := range pkgs {
+		okBuild[p] = true
+	}
+	warned := false
+	for _, a := range actionList(root) {
+		if a.p == nil || okBuild[a.p] {
+			continue
+		}
+		okBuild[a.p] = true // warn at most once
+
+		// Don't warn about packages being rebuilt because of
+		// things like coverage analysis.
+		for _, p1 := range a.p.imports {
+			if p1.fake {
+				a.p.fake = true
+			}
+		}
+
+		if a.f != nil && !okBuild[a.p] && !a.p.fake && !a.p.local {
+			if !warned {
+				fmt.Fprintf(os.Stderr, "warning: building out-of-date packages:\n")
+				warned = true
+			}
+			fmt.Fprintf(os.Stderr, "\t%s\n", a.p.ImportPath)
+		}
+	}
+	if warned {
+		args := strings.Join(pkgArgs, " ")
+		if args != "" {
+			args = " " + args
+		}
+		extraOpts := ""
+		if buildRace {
+			extraOpts = "-race "
+		}
+		fmt.Fprintf(os.Stderr, "installing these packages with 'go test %s-i%s' will speed future tests.\n\n", extraOpts, args)
+	}
+
+	b.do(root)
+}
+
+func contains(x []string, s string) bool {
+	for _, t := range x {
+		if t == s {
+			return true
+		}
+	}
+	return false
+}
+
+func (b *builder) test(p *Package) (buildAction, runAction, printAction *action, err error) {
+	if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
+		build := b.action(modeBuild, modeBuild, p)
+		run := &action{p: p, deps: []*action{build}}
+		print := &action{f: (*builder).notest, p: p, deps: []*action{run}}
+		return build, run, print, nil
+	}
+
+	// Build Package structs describing:
+	//	ptest - package + test files
+	//	pxtest - package of external test files
+	//	pmain - pkg.test binary
+	var ptest, pxtest, pmain *Package
+
+	var imports, ximports []*Package
+	var stk importStack
+	stk.push(p.ImportPath + " (test)")
+	for _, path := range p.TestImports {
+		p1 := loadImport(path, p.Dir, &stk, p.build.TestImportPos[path])
+		if !reqPkgSrc && p1.Root == "" {
+			continue
+		}
+		if p1.Error != nil {
+			return nil, nil, nil, p1.Error
+		}
+		if contains(p1.Deps, p.ImportPath) {
+			// Same error that loadPackage returns (via reusePackage) in pkg.go.
+			// Can't change that code, because that code is only for loading the
+			// non-test copy of a package.
+			err := &PackageError{
+				ImportStack:   testImportStack(stk[0], p1, p.ImportPath),
+				Err:           "import cycle not allowed in test",
+				isImportCycle: true,
+			}
+			return nil, nil, nil, err
+		}
+		imports = append(imports, p1)
+	}
+	stk.pop()
+	stk.push(p.ImportPath + "_test")
+	pxtestNeedsPtest := false
+	for _, path := range p.XTestImports {
+		if path == p.ImportPath {
+			pxtestNeedsPtest = true
+			continue
+		}
+		p1 := loadImport(path, p.Dir, &stk, p.build.XTestImportPos[path])
+		if !reqPkgSrc && p1.Root == "" {
+			continue
+		}
+		if p1.Error != nil {
+			return nil, nil, nil, p1.Error
+		}
+		ximports = append(ximports, p1)
+	}
+	stk.pop()
+
+	// Use last element of import path, not package name.
+	// They differ when package name is "main".
+	// But if the import path is "command-line-arguments",
+	// like it is during 'go run', use the package name.
+	var elem string
+	if p.ImportPath == "command-line-arguments" {
+		elem = p.Name
+	} else {
+		_, elem = path.Split(p.ImportPath)
+	}
+	testBinary := elem + ".test"
+
+	// The ptest package needs to be importable under the
+	// same import path that p has, but we cannot put it in
+	// the usual place in the temporary tree, because then
+	// other tests will see it as the real package.
+	// Instead we make a _test directory under the import path
+	// and then repeat the import path there.  We tell the
+	// compiler and linker to look in that _test directory first.
+	//
+	// That is, if the package under test is unicode/utf8,
+	// then the normal place to write the package archive is
+	// $WORK/unicode/utf8.a, but we write the test package archive to
+	// $WORK/unicode/utf8/_test/unicode/utf8.a.
+	// We write the external test package archive to
+	// $WORK/unicode/utf8/_test/unicode/utf8_test.a.
+	testDir := filepath.Join(b.work, filepath.FromSlash(p.ImportPath+"/_test"))
+	ptestObj := buildToolchain.pkgpath(testDir, p)
+
+	// Create the directory for the .a files.
+	ptestDir, _ := filepath.Split(ptestObj)
+	if err := b.mkdir(ptestDir); err != nil {
+		return nil, nil, nil, err
+	}
+
+	// Should we apply coverage analysis locally,
+	// only for this package and only for this test?
+	// Yes, if -cover is on but -coverpkg has not specified
+	// a list of packages for global coverage.
+	localCover := testCover && testCoverPaths == nil
+
+	// Test package.
+	if len(p.TestGoFiles) > 0 || localCover || p.Name == "main" {
+		ptest = new(Package)
+		*ptest = *p
+		ptest.GoFiles = nil
+		ptest.GoFiles = append(ptest.GoFiles, p.GoFiles...)
+		ptest.GoFiles = append(ptest.GoFiles, p.TestGoFiles...)
+		ptest.target = ""
+		ptest.Imports = stringList(p.Imports, p.TestImports)
+		ptest.imports = append(append([]*Package{}, p.imports...), imports...)
+		ptest.pkgdir = testDir
+		ptest.fake = true
+		ptest.forceLibrary = true
+		ptest.Stale = true
+		ptest.build = new(build.Package)
+		*ptest.build = *p.build
+		m := map[string][]token.Position{}
+		for k, v := range p.build.ImportPos {
+			m[k] = append(m[k], v...)
+		}
+		for k, v := range p.build.TestImportPos {
+			m[k] = append(m[k], v...)
+		}
+		ptest.build.ImportPos = m
+
+		if localCover {
+			ptest.coverMode = testCoverMode
+			var coverFiles []string
+			coverFiles = append(coverFiles, ptest.GoFiles...)
+			coverFiles = append(coverFiles, ptest.CgoFiles...)
+			ptest.coverVars = declareCoverVars(ptest.ImportPath, coverFiles...)
+		}
+	} else {
+		ptest = p
+	}
+
+	// External test package.
+	if len(p.XTestGoFiles) > 0 {
+		pxtest = &Package{
+			Name:        p.Name + "_test",
+			ImportPath:  p.ImportPath + "_test",
+			localPrefix: p.localPrefix,
+			Root:        p.Root,
+			Dir:         p.Dir,
+			GoFiles:     p.XTestGoFiles,
+			Imports:     p.XTestImports,
+			build: &build.Package{
+				ImportPos: p.build.XTestImportPos,
+			},
+			imports: ximports,
+			pkgdir:  testDir,
+			fake:    true,
+			Stale:   true,
+		}
+		if pxtestNeedsPtest {
+			pxtest.imports = append(pxtest.imports, ptest)
+		}
+	}
+
+	// Action for building pkg.test.
+	pmain = &Package{
+		Name:       "main",
+		Dir:        testDir,
+		GoFiles:    []string{"_testmain.go"},
+		ImportPath: "testmain",
+		Root:       p.Root,
+		build:      &build.Package{Name: "main"},
+		pkgdir:     testDir,
+		fake:       true,
+		Stale:      true,
+		omitDWARF:  !testC && !testNeedBinary,
+	}
+
+	// The generated main also imports testing and regexp.
+	stk.push("testmain")
+	for dep := range testMainDeps {
+		if dep == ptest.ImportPath {
+			pmain.imports = append(pmain.imports, ptest)
+		} else {
+			p1 := loadImport(dep, "", &stk, nil)
+			if !reqPkgSrc && p1.Root == "" {
+				continue
+			}
+			if p1.Error != nil {
+				return nil, nil, nil, p1.Error
+			}
+			pmain.imports = append(pmain.imports, p1)
+		}
+	}
+
+	if testCoverPkgs != nil {
+		// Add imports, but avoid duplicates.
+		seen := map[*Package]bool{p: true, ptest: true}
+		for _, p1 := range pmain.imports {
+			seen[p1] = true
+		}
+		for _, p1 := range testCoverPkgs {
+			if !seen[p1] {
+				seen[p1] = true
+				pmain.imports = append(pmain.imports, p1)
+			}
+		}
+	}
+
+	// Do initial scan for metadata needed for writing _testmain.go
+	// Use that metadata to update the list of imports for package main.
+	// The list of imports is used by recompileForTest and by the loop
+	// afterward that gathers t.Cover information.
+	t, err := loadTestFuncs(ptest)
+	if err != nil {
+		return nil, nil, nil, err
+	}
+	if t.NeedTest || ptest.coverMode != "" {
+		pmain.imports = append(pmain.imports, ptest)
+	}
+	if t.NeedXtest {
+		pmain.imports = append(pmain.imports, pxtest)
+	}
+
+	if ptest != p && localCover {
+		// We have made modifications to the package p being tested
+		// and are rebuilding p (as ptest), writing it to the testDir tree.
+		// Arrange to rebuild, writing to that same tree, all packages q
+		// such that the test depends on q, and q depends on p.
+		// This makes sure that q sees the modifications to p.
+		// Strictly speaking, the rebuild is only necessary if the
+		// modifications to p change its export metadata, but
+		// determining that is a bit tricky, so we rebuild always.
+		//
+		// This will cause extra compilation, so for now we only do it
+		// when testCover is set. The conditions are more general, though,
+		// and we may find that we need to do it always in the future.
+		recompileForTest(pmain, p, ptest, testDir)
+	}
+
+	for _, cp := range pmain.imports {
+		if len(cp.coverVars) > 0 {
+			t.Cover = append(t.Cover, coverInfo{cp, cp.coverVars})
+		}
+	}
+
+	// writeTestmain writes _testmain.go. This must happen after recompileForTest,
+	// because recompileForTest modifies XXX.
+	if err := writeTestmain(filepath.Join(testDir, "_testmain.go"), t); err != nil {
+		return nil, nil, nil, err
+	}
+
+	computeStale(pmain)
+
+	if ptest != p {
+		a := b.action(modeBuild, modeBuild, ptest)
+		a.objdir = testDir + string(filepath.Separator) + "_obj_test" + string(filepath.Separator)
+		a.objpkg = ptestObj
+		a.target = ptestObj
+		a.link = false
+	}
+
+	if pxtest != nil {
+		a := b.action(modeBuild, modeBuild, pxtest)
+		a.objdir = testDir + string(filepath.Separator) + "_obj_xtest" + string(filepath.Separator)
+		a.objpkg = buildToolchain.pkgpath(testDir, pxtest)
+		a.target = a.objpkg
+	}
+
+	a := b.action(modeBuild, modeBuild, pmain)
+	a.objdir = testDir + string(filepath.Separator)
+	a.objpkg = filepath.Join(testDir, "main.a")
+	a.target = filepath.Join(testDir, testBinary) + exeSuffix
+	pmainAction := a
+
+	if testC || testNeedBinary {
+		// -c or profiling flag: create action to copy binary to ./test.out.
+		runAction = &action{
+			f:      (*builder).install,
+			deps:   []*action{pmainAction},
+			p:      pmain,
+			target: filepath.Join(cwd, testBinary+exeSuffix),
+		}
+		pmainAction = runAction // in case we are running the test
+	}
+	if testC {
+		printAction = &action{p: p, deps: []*action{runAction}} // nop
+	} else {
+		// run test
+		runAction = &action{
+			f:          (*builder).runTest,
+			deps:       []*action{pmainAction},
+			p:          p,
+			ignoreFail: true,
+		}
+		cleanAction := &action{
+			f:    (*builder).cleanTest,
+			deps: []*action{runAction},
+			p:    p,
+		}
+		printAction = &action{
+			f:    (*builder).printTest,
+			deps: []*action{cleanAction},
+			p:    p,
+		}
+	}
+
+	return pmainAction, runAction, printAction, nil
+}
+
+func testImportStack(top string, p *Package, target string) []string {
+	stk := []string{top, p.ImportPath}
+Search:
+	for p.ImportPath != target {
+		for _, p1 := range p.imports {
+			if p1.ImportPath == target || contains(p1.Deps, target) {
+				stk = append(stk, p1.ImportPath)
+				p = p1
+				continue Search
+			}
+		}
+		// Can't happen, but in case it does...
+		stk = append(stk, "<lost path to cycle>")
+		break
+	}
+	return stk
+}
+
+func recompileForTest(pmain, preal, ptest *Package, testDir string) {
+	// The "test copy" of preal is ptest.
+	// For each package that depends on preal, make a "test copy"
+	// that depends on ptest. And so on, up the dependency tree.
+	testCopy := map[*Package]*Package{preal: ptest}
+	for _, p := range packageList([]*Package{pmain}) {
+		// Copy on write.
+		didSplit := false
+		split := func() {
+			if didSplit {
+				return
+			}
+			didSplit = true
+			if p.pkgdir != testDir {
+				p1 := new(Package)
+				testCopy[p] = p1
+				*p1 = *p
+				p1.imports = make([]*Package, len(p.imports))
+				copy(p1.imports, p.imports)
+				p = p1
+				p.pkgdir = testDir
+				p.target = ""
+				p.fake = true
+				p.Stale = true
+			}
+		}
+
+		// Update p.deps and p.imports to use at test copies.
+		for i, dep := range p.deps {
+			if p1 := testCopy[dep]; p1 != nil && p1 != dep {
+				split()
+				p.deps[i] = p1
+			}
+		}
+		for i, imp := range p.imports {
+			if p1 := testCopy[imp]; p1 != nil && p1 != imp {
+				split()
+				p.imports[i] = p1
+			}
+		}
+	}
+}
+
+var coverIndex = 0
+
+// isTestFile reports whether the source file is a set of tests and should therefore
+// be excluded from coverage analysis.
+func isTestFile(file string) bool {
+	// We don't cover tests, only the code they test.
+	return strings.HasSuffix(file, "_test.go")
+}
+
+// declareCoverVars attaches the required cover variables names
+// to the files, to be used when annotating the files.
+func declareCoverVars(importPath string, files ...string) map[string]*CoverVar {
+	coverVars := make(map[string]*CoverVar)
+	for _, file := range files {
+		if isTestFile(file) {
+			continue
+		}
+		coverVars[file] = &CoverVar{
+			File: filepath.Join(importPath, file),
+			Var:  fmt.Sprintf("GoCover_%d", coverIndex),
+		}
+		coverIndex++
+	}
+	return coverVars
+}
+
+// runTest is the action for running a test binary.
+func (b *builder) runTest(a *action) error {
+	args := stringList(findExecCmd(), a.deps[0].target, testArgs)
+	a.testOutput = new(bytes.Buffer)
+
+	if buildN || buildX {
+		b.showcmd("", "%s", strings.Join(args, " "))
+		if buildN {
+			return nil
+		}
+	}
+
+	if a.failed {
+		// We were unable to build the binary.
+		a.failed = false
+		fmt.Fprintf(a.testOutput, "FAIL\t%s [build failed]\n", a.p.ImportPath)
+		setExitStatus(1)
+		return nil
+	}
+
+	cmd := exec.Command(args[0], args[1:]...)
+	cmd.Dir = a.p.Dir
+	cmd.Env = envForDir(cmd.Dir)
+	var buf bytes.Buffer
+	if testStreamOutput {
+		cmd.Stdout = os.Stdout
+		cmd.Stderr = os.Stderr
+	} else {
+		cmd.Stdout = &buf
+		cmd.Stderr = &buf
+	}
+
+	// If there are any local SWIG dependencies, we want to load
+	// the shared library from the build directory.
+	if a.p.usesSwig() {
+		env := cmd.Env
+		found := false
+		prefix := "LD_LIBRARY_PATH="
+		for i, v := range env {
+			if strings.HasPrefix(v, prefix) {
+				env[i] = v + ":."
+				found = true
+				break
+			}
+		}
+		if !found {
+			env = append(env, "LD_LIBRARY_PATH=.")
+		}
+		cmd.Env = env
+	}
+
+	t0 := time.Now()
+	err := cmd.Start()
+
+	// This is a last-ditch deadline to detect and
+	// stop wedged test binaries, to keep the builders
+	// running.
+	if err == nil {
+		tick := time.NewTimer(testKillTimeout)
+		startSigHandlers()
+		done := make(chan error)
+		go func() {
+			done <- cmd.Wait()
+		}()
+	Outer:
+		select {
+		case err = <-done:
+			// ok
+		case <-tick.C:
+			if signalTrace != nil {
+				// Send a quit signal in the hope that the program will print
+				// a stack trace and exit. Give it five seconds before resorting
+				// to Kill.
+				cmd.Process.Signal(signalTrace)
+				select {
+				case err = <-done:
+					fmt.Fprintf(&buf, "*** Test killed with %v: ran too long (%v).\n", signalTrace, testKillTimeout)
+					break Outer
+				case <-time.After(5 * time.Second):
+				}
+			}
+			cmd.Process.Kill()
+			err = <-done
+			fmt.Fprintf(&buf, "*** Test killed: ran too long (%v).\n", testKillTimeout)
+		}
+		tick.Stop()
+	}
+	out := buf.Bytes()
+	t := fmt.Sprintf("%.3fs", time.Since(t0).Seconds())
+	if err == nil {
+		if testShowPass {
+			a.testOutput.Write(out)
+		}
+		fmt.Fprintf(a.testOutput, "ok  \t%s\t%s%s\n", a.p.ImportPath, t, coveragePercentage(out))
+		return nil
+	}
+
+	setExitStatus(1)
+	if len(out) > 0 {
+		a.testOutput.Write(out)
+		// assume printing the test binary's exit status is superfluous
+	} else {
+		fmt.Fprintf(a.testOutput, "%s\n", err)
+	}
+	fmt.Fprintf(a.testOutput, "FAIL\t%s\t%s\n", a.p.ImportPath, t)
+
+	return nil
+}
+
+// coveragePercentage returns the coverage results (if enabled) for the
+// test. It uncovers the data by scanning the output from the test run.
+func coveragePercentage(out []byte) string {
+	if !testCover {
+		return ""
+	}
+	// The string looks like
+	//	test coverage for encoding/binary: 79.9% of statements
+	// Extract the piece from the percentage to the end of the line.
+	re := regexp.MustCompile(`coverage: (.*)\n`)
+	matches := re.FindSubmatch(out)
+	if matches == nil {
+		// Probably running "go test -cover" not "go test -cover fmt".
+		// The coverage output will appear in the output directly.
+		return ""
+	}
+	return fmt.Sprintf("\tcoverage: %s", matches[1])
+}
+
+// cleanTest is the action for cleaning up after a test.
+func (b *builder) cleanTest(a *action) error {
+	if buildWork {
+		return nil
+	}
+	run := a.deps[0]
+	testDir := filepath.Join(b.work, filepath.FromSlash(run.p.ImportPath+"/_test"))
+	os.RemoveAll(testDir)
+	return nil
+}
+
+// printTest is the action for printing a test result.
+func (b *builder) printTest(a *action) error {
+	clean := a.deps[0]
+	run := clean.deps[0]
+	os.Stdout.Write(run.testOutput.Bytes())
+	run.testOutput = nil
+	return nil
+}
+
+// notest is the action for testing a package with no test files.
+func (b *builder) notest(a *action) error {
+	fmt.Printf("?   \t%s\t[no test files]\n", a.p.ImportPath)
+	return nil
+}
+
+// isTest tells whether name looks like a test (or benchmark, according to prefix).
+// It is a Test (say) if there is a character after Test that is not a lower-case letter.
+// We don't want TesticularCancer.
+func isTest(name, prefix string) bool {
+	if !strings.HasPrefix(name, prefix) {
+		return false
+	}
+	if len(name) == len(prefix) { // "Test" is ok
+		return true
+	}
+	rune, _ := utf8.DecodeRuneInString(name[len(prefix):])
+	return !unicode.IsLower(rune)
+}
+
+type coverInfo struct {
+	Package *Package
+	Vars    map[string]*CoverVar
+}
+
+// loadTestFuncs returns the testFuncs describing the tests that will be run.
+func loadTestFuncs(ptest *Package) (*testFuncs, error) {
+	t := &testFuncs{
+		Package: ptest,
+	}
+	for _, file := range ptest.TestGoFiles {
+		if err := t.load(filepath.Join(ptest.Dir, file), "_test", &t.NeedTest); err != nil {
+			return nil, err
+		}
+	}
+	for _, file := range ptest.XTestGoFiles {
+		if err := t.load(filepath.Join(ptest.Dir, file), "_xtest", &t.NeedXtest); err != nil {
+			return nil, err
+		}
+	}
+	return t, nil
+}
+
+// writeTestmain writes the _testmain.go file for t to the file named out.
+func writeTestmain(out string, t *testFuncs) error {
+	f, err := os.Create(out)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	if err := testmainTmpl.Execute(f, t); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+type testFuncs struct {
+	Tests      []testFunc
+	Benchmarks []testFunc
+	Examples   []testFunc
+	Package    *Package
+	NeedTest   bool
+	NeedXtest  bool
+	Cover      []coverInfo
+}
+
+func (t *testFuncs) CoverMode() string {
+	return testCoverMode
+}
+
+func (t *testFuncs) CoverEnabled() bool {
+	return testCover
+}
+
+// Covered returns a string describing which packages are being tested for coverage.
+// If the covered package is the same as the tested package, it returns the empty string.
+// Otherwise it is a comma-separated human-readable list of packages beginning with
+// " in", ready for use in the coverage message.
+func (t *testFuncs) Covered() string {
+	if testCoverPaths == nil {
+		return ""
+	}
+	return " in " + strings.Join(testCoverPaths, ", ")
+}
+
+// Tested returns the name of the package being tested.
+func (t *testFuncs) Tested() string {
+	return t.Package.Name
+}
+
+type testFunc struct {
+	Package string // imported package name (_test or _xtest)
+	Name    string // function name
+	Output  string // output, for examples
+}
+
+var testFileSet = token.NewFileSet()
+
+func (t *testFuncs) load(filename, pkg string, seen *bool) error {
+	f, err := parser.ParseFile(testFileSet, filename, nil, parser.ParseComments)
+	if err != nil {
+		return expandScanner(err)
+	}
+	for _, d := range f.Decls {
+		n, ok := d.(*ast.FuncDecl)
+		if !ok {
+			continue
+		}
+		if n.Recv != nil {
+			continue
+		}
+		name := n.Name.String()
+		switch {
+		case isTest(name, "Test"):
+			t.Tests = append(t.Tests, testFunc{pkg, name, ""})
+			*seen = true
+		case isTest(name, "Benchmark"):
+			t.Benchmarks = append(t.Benchmarks, testFunc{pkg, name, ""})
+			*seen = true
+		}
+	}
+	ex := doc.Examples(f)
+	sort.Sort(byOrder(ex))
+	for _, e := range ex {
+		if e.Output == "" && !e.EmptyOutput {
+			// Don't run examples with no output.
+			continue
+		}
+		t.Examples = append(t.Examples, testFunc{pkg, "Example" + e.Name, e.Output})
+		*seen = true
+	}
+	return nil
+}
+
+type byOrder []*doc.Example
+
+func (x byOrder) Len() int           { return len(x) }
+func (x byOrder) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
+func (x byOrder) Less(i, j int) bool { return x[i].Order < x[j].Order }
+
+var testmainTmpl = template.Must(template.New("main").Parse(`
+package main
+
+import (
+	"regexp"
+	"testing"
+
+{{if .NeedTest}}
+	_test {{.Package.ImportPath | printf "%q"}}
+{{end}}
+{{if .NeedXtest}}
+	_xtest {{.Package.ImportPath | printf "%s_test" | printf "%q"}}
+{{end}}
+{{range $i, $p := .Cover}}
+	_cover{{$i}} {{$p.Package.ImportPath | printf "%q"}}
+{{end}}
+)
+
+var tests = []testing.InternalTest{
+{{range .Tests}}
+	{"{{.Name}}", {{.Package}}.{{.Name}}},
+{{end}}
+}
+
+var benchmarks = []testing.InternalBenchmark{
+{{range .Benchmarks}}
+	{"{{.Name}}", {{.Package}}.{{.Name}}},
+{{end}}
+}
+
+var examples = []testing.InternalExample{
+{{range .Examples}}
+	{"{{.Name}}", {{.Package}}.{{.Name}}, {{.Output | printf "%q"}}},
+{{end}}
+}
+
+var matchPat string
+var matchRe *regexp.Regexp
+
+func matchString(pat, str string) (result bool, err error) {
+	if matchRe == nil || matchPat != pat {
+		matchPat = pat
+		matchRe, err = regexp.Compile(matchPat)
+		if err != nil {
+			return
+		}
+	}
+	return matchRe.MatchString(str), nil
+}
+
+{{if .CoverEnabled}}
+
+// Only updated by init functions, so no need for atomicity.
+var (
+	coverCounters = make(map[string][]uint32)
+	coverBlocks = make(map[string][]testing.CoverBlock)
+)
+
+func init() {
+	{{range $i, $p := .Cover}}
+	{{range $file, $cover := $p.Vars}}
+	coverRegisterFile({{printf "%q" $cover.File}}, _cover{{$i}}.{{$cover.Var}}.Count[:], _cover{{$i}}.{{$cover.Var}}.Pos[:], _cover{{$i}}.{{$cover.Var}}.NumStmt[:])
+	{{end}}
+	{{end}}
+}
+
+func coverRegisterFile(fileName string, counter []uint32, pos []uint32, numStmts []uint16) {
+	if 3*len(counter) != len(pos) || len(counter) != len(numStmts) {
+		panic("coverage: mismatched sizes")
+	}
+	if coverCounters[fileName] != nil {
+		// Already registered.
+		return
+	}
+	coverCounters[fileName] = counter
+	block := make([]testing.CoverBlock, len(counter))
+	for i := range counter {
+		block[i] = testing.CoverBlock{
+			Line0: pos[3*i+0],
+			Col0: uint16(pos[3*i+2]),
+			Line1: pos[3*i+1],
+			Col1: uint16(pos[3*i+2]>>16),
+			Stmts: numStmts[i],
+		}
+	}
+	coverBlocks[fileName] = block
+}
+{{end}}
+
+func main() {
+{{if .CoverEnabled}}
+	testing.RegisterCover(testing.Cover{
+		Mode: {{printf "%q" .CoverMode}},
+		Counters: coverCounters,
+		Blocks: coverBlocks,
+		CoveredPackages: {{printf "%q" .Covered}},
+	})
+{{end}}
+	testing.Main(matchString, tests, benchmarks, examples)
+}
+
+`))
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/cgocover/p.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/cgocover/p.go
new file mode 100644
index 0000000..a6a3891
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/cgocover/p.go
@@ -0,0 +1,19 @@
+package p
+
+/*
+void
+f(void)
+{
+}
+*/
+import "C"
+
+var b bool
+
+func F() {
+	if b {
+		for {
+		}
+	}
+	C.f()
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/cgocover/p_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/cgocover/p_test.go
new file mode 100644
index 0000000..a8f057e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/cgocover/p_test.go
@@ -0,0 +1,7 @@
+package p
+
+import "testing"
+
+func TestF(t *testing.T) {
+	F()
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/dep_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/dep_test.go
new file mode 100644
index 0000000..0c53ac4
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/dep_test.go
@@ -0,0 +1,7 @@
+// 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 deps
+
+import _ "testing"
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/example1_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/example1_test.go
new file mode 100644
index 0000000..ec7092e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/example1_test.go
@@ -0,0 +1,23 @@
+// Copyright 2013 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.
+
+// Make sure that go test runs Example_Z before Example_A, preserving source order.
+
+package p
+
+import "fmt"
+
+var n int
+
+func Example_Z() {
+	n++
+	fmt.Println(n)
+	// Output: 1
+}
+
+func Example_A() {
+	n++
+	fmt.Println(n)
+	// Output: 2
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/example2_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/example2_test.go
new file mode 100644
index 0000000..1e0e80b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/example2_test.go
@@ -0,0 +1,21 @@
+// Copyright 2013 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.
+
+// Make sure that go test runs Example_Y before Example_B, preserving source order.
+
+package p
+
+import "fmt"
+
+func Example_Y() {
+	n++
+	fmt.Println(n)
+	// Output: 3
+}
+
+func Example_B() {
+	n++
+	fmt.Println(n)
+	// Output: 4
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/local/easy.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/local/easy.go
new file mode 100644
index 0000000..4eeb517
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/local/easy.go
@@ -0,0 +1,7 @@
+package main
+
+import "./easysub"
+
+func main() {
+	easysub.Hello()
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/local/easysub/easysub.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/local/easysub/easysub.go
new file mode 100644
index 0000000..07040da
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/local/easysub/easysub.go
@@ -0,0 +1,7 @@
+package easysub
+
+import "fmt"
+
+func Hello() {
+	fmt.Println("easysub.Hello")
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/local/easysub/main.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/local/easysub/main.go
new file mode 100644
index 0000000..6c30b52
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/local/easysub/main.go
@@ -0,0 +1,9 @@
+// +build ignore
+
+package main
+
+import "."
+
+func main() {
+	easysub.Hello()
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/local/hard.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/local/hard.go
new file mode 100644
index 0000000..2ffac3f
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/local/hard.go
@@ -0,0 +1,7 @@
+package main
+
+import "./sub"
+
+func main() {
+	sub.Hello()
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/local/sub/sub.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/local/sub/sub.go
new file mode 100644
index 0000000..d5dbf6d
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/local/sub/sub.go
@@ -0,0 +1,12 @@
+package sub
+
+import (
+	"fmt"
+
+	subsub "./sub"
+)
+
+func Hello() {
+	fmt.Println("sub.Hello")
+	subsub.Hello()
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/local/sub/sub/subsub.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/local/sub/sub/subsub.go
new file mode 100644
index 0000000..4cc7223
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/local/sub/sub/subsub.go
@@ -0,0 +1,7 @@
+package subsub
+
+import "fmt"
+
+func Hello() {
+	fmt.Println("subsub.Hello")
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/shadow/root1/src/foo/foo.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/shadow/root1/src/foo/foo.go
new file mode 100644
index 0000000..f52652b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/shadow/root1/src/foo/foo.go
@@ -0,0 +1 @@
+package foo
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/shadow/root1/src/math/math.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/shadow/root1/src/math/math.go
new file mode 100644
index 0000000..c91c24e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/shadow/root1/src/math/math.go
@@ -0,0 +1 @@
+package math
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/shadow/root2/src/foo/foo.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/shadow/root2/src/foo/foo.go
new file mode 100644
index 0000000..f52652b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/shadow/root2/src/foo/foo.go
@@ -0,0 +1 @@
+package foo
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/badpkg/x.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/badpkg/x.go
new file mode 100644
index 0000000..dda35e8
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/badpkg/x.go
@@ -0,0 +1 @@
+pkg badpkg
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/cgotest/m.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/cgotest/m.go
new file mode 100644
index 0000000..4d68307
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/cgotest/m.go
@@ -0,0 +1,5 @@
+package cgotest
+
+import "C"
+
+var _ C.int
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/go-cmd-test/helloworld.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/go-cmd-test/helloworld.go
new file mode 100644
index 0000000..002a5c7
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/go-cmd-test/helloworld.go
@@ -0,0 +1,5 @@
+package main
+
+func main() {
+	println("hello world")
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/main_test/m.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/main_test/m.go
new file mode 100644
index 0000000..c682f03
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/main_test/m.go
@@ -0,0 +1,4 @@
+package main
+
+func F()    {}
+func main() {}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/main_test/m_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/main_test/m_test.go
new file mode 100644
index 0000000..f865b77
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/main_test/m_test.go
@@ -0,0 +1,10 @@
+package main_test
+
+import (
+	. "main_test"
+	"testing"
+)
+
+func Test1(t *testing.T) {
+	F()
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/notest/hello.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/notest/hello.go
new file mode 100644
index 0000000..7c42c32
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/notest/hello.go
@@ -0,0 +1,6 @@
+package notest
+
+func hello() {
+	println("hello world")
+}
+Hello world
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/syntaxerror/x.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/syntaxerror/x.go
new file mode 100644
index 0000000..c89cd18
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/syntaxerror/x.go
@@ -0,0 +1 @@
+package p
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/syntaxerror/x_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/syntaxerror/x_test.go
new file mode 100644
index 0000000..2460743
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/syntaxerror/x_test.go
@@ -0,0 +1,4 @@
+package p
+
+func f() (x.y, z int) {
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/p1/p1.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/p1/p1.go
new file mode 100644
index 0000000..65ab76d
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/p1/p1.go
@@ -0,0 +1,7 @@
+package p1
+
+import _ "testcycle/p2"
+
+func init() {
+	println("p1 init")
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/p1/p1_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/p1/p1_test.go
new file mode 100644
index 0000000..75abb13
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/p1/p1_test.go
@@ -0,0 +1,6 @@
+package p1
+
+import "testing"
+
+func Test(t *testing.T) {
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/p2/p2.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/p2/p2.go
new file mode 100644
index 0000000..7e26cdf
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/p2/p2.go
@@ -0,0 +1,7 @@
+package p2
+
+import _ "testcycle/p3"
+
+func init() {
+	println("p2 init")
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/p3/p3.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/p3/p3.go
new file mode 100644
index 0000000..bb0a2f4
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/p3/p3.go
@@ -0,0 +1,5 @@
+package p3
+
+func init() {
+	println("p3 init")
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/p3/p3_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/p3/p3_test.go
new file mode 100644
index 0000000..9b4b075
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/testcycle/p3/p3_test.go
@@ -0,0 +1,10 @@
+package p3
+
+import (
+	"testing"
+
+	_ "testcycle/p1"
+)
+
+func Test(t *testing.T) {
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/xtestonly/f.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/xtestonly/f.go
new file mode 100644
index 0000000..dac039e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/xtestonly/f.go
@@ -0,0 +1,3 @@
+package xtestonly
+
+func F() int { return 42 }
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/src/xtestonly/f_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/xtestonly/f_test.go
new file mode 100644
index 0000000..01f6e83
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/src/xtestonly/f_test.go
@@ -0,0 +1,12 @@
+package xtestonly_test
+
+import (
+	"testing"
+	"xtestonly"
+)
+
+func TestF(t *testing.T) {
+	if x := xtestonly.F(); x != 42 {
+		t.Errorf("f.F() = %d, want 42", x)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/standalone_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/standalone_test.go
new file mode 100644
index 0000000..59cf918
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/standalone_test.go
@@ -0,0 +1,6 @@
+package standalone_test
+
+import "testing"
+
+func Test(t *testing.T) {
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/testimport/p.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/testimport/p.go
new file mode 100644
index 0000000..f94d2cd
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/testimport/p.go
@@ -0,0 +1,3 @@
+package p
+
+func F() int { return 1 }
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/testimport/p1/p1.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/testimport/p1/p1.go
new file mode 100644
index 0000000..fd31527
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/testimport/p1/p1.go
@@ -0,0 +1,3 @@
+package p1
+
+func F() int { return 1 }
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/testimport/p2/p2.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/testimport/p2/p2.go
new file mode 100644
index 0000000..d488886
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/testimport/p2/p2.go
@@ -0,0 +1,3 @@
+package p2
+
+func F() int { return 1 }
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/testimport/p_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/testimport/p_test.go
new file mode 100644
index 0000000..a3fb4a9
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/testimport/p_test.go
@@ -0,0 +1,13 @@
+package p
+
+import (
+	"./p1"
+
+	"testing"
+)
+
+func TestF(t *testing.T) {
+	if F() != p1.F() {
+		t.Fatal(F())
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/testimport/x_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/testimport/x_test.go
new file mode 100644
index 0000000..b253e3f
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/testimport/x_test.go
@@ -0,0 +1,15 @@
+package p_test
+
+import (
+	. "../testimport"
+
+	"./p2"
+
+	"testing"
+)
+
+func TestF1(t *testing.T) {
+	if F() != p2.F() {
+		t.Fatal(F())
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testdata/testonly/p_test.go b/third_party/gofrontend/libgo/go/cmd/go/testdata/testonly/p_test.go
new file mode 100644
index 0000000..c89cd18
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testdata/testonly/p_test.go
@@ -0,0 +1 @@
+package p
diff --git a/third_party/gofrontend/libgo/go/cmd/go/testflag.go b/third_party/gofrontend/libgo/go/cmd/go/testflag.go
new file mode 100644
index 0000000..73f311e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/testflag.go
@@ -0,0 +1,318 @@
+// Copyright 2011 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"
+	"os"
+	"strconv"
+	"strings"
+)
+
+// The flag handling part of go test is large and distracting.
+// We can't use the flag package because some of the flags from
+// our command line are for us, and some are for 6.out, and
+// some are for both.
+
+var usageMessage = `Usage of go test:
+  -c=false: compile but do not run the test binary
+  -file=file_test.go: specify file to use for tests;
+      use multiple times for multiple files
+  -p=n: build and test up to n packages in parallel
+  -x=false: print command lines as they are executed
+
+  // These flags can be passed with or without a "test." prefix: -v or -test.v.
+  -bench="": passes -test.bench to test
+  -benchmem=false: print memory allocation statistics for benchmarks
+  -benchtime=1s: passes -test.benchtime to test
+  -cover=false: enable coverage analysis
+  -covermode="set": specifies mode for coverage analysis
+  -coverpkg="": comma-separated list of packages for coverage analysis
+  -coverprofile="": passes -test.coverprofile to test if -cover
+  -cpu="": passes -test.cpu to test
+  -cpuprofile="": passes -test.cpuprofile to test
+  -memprofile="": passes -test.memprofile to test
+  -memprofilerate=0: passes -test.memprofilerate to test
+  -blockprofile="": pases -test.blockprofile to test
+  -blockprofilerate=0: passes -test.blockprofilerate to test
+  -outputdir=$PWD: passes -test.outputdir to test
+  -parallel=0: passes -test.parallel to test
+  -run="": passes -test.run to test
+  -short=false: passes -test.short to test
+  -timeout=0: passes -test.timeout to test
+  -v=false: passes -test.v to test
+`
+
+// usage prints a usage message and exits.
+func testUsage() {
+	fmt.Fprint(os.Stderr, usageMessage)
+	setExitStatus(2)
+	exit()
+}
+
+// testFlagSpec defines a flag we know about.
+type testFlagSpec struct {
+	name       string
+	boolVar    *bool
+	passToTest bool // pass to Test
+	multiOK    bool // OK to have multiple instances
+	present    bool // flag has been seen
+}
+
+// testFlagDefn is the set of flags we process.
+var testFlagDefn = []*testFlagSpec{
+	// local.
+	{name: "c", boolVar: &testC},
+	{name: "file", multiOK: true},
+	{name: "cover", boolVar: &testCover},
+	{name: "coverpkg"},
+
+	// build flags.
+	{name: "a", boolVar: &buildA},
+	{name: "n", boolVar: &buildN},
+	{name: "p"},
+	{name: "x", boolVar: &buildX},
+	{name: "i", boolVar: &buildI},
+	{name: "work", boolVar: &buildWork},
+	{name: "ccflags"},
+	{name: "gcflags"},
+	{name: "exec"},
+	{name: "ldflags"},
+	{name: "gccgoflags"},
+	{name: "tags"},
+	{name: "compiler"},
+	{name: "race", boolVar: &buildRace},
+	{name: "installsuffix"},
+
+	// passed to 6.out, adding a "test." prefix to the name if necessary: -v becomes -test.v.
+	{name: "bench", passToTest: true},
+	{name: "benchmem", boolVar: new(bool), passToTest: true},
+	{name: "benchtime", passToTest: true},
+	{name: "covermode"},
+	{name: "coverprofile", passToTest: true},
+	{name: "cpu", passToTest: true},
+	{name: "cpuprofile", passToTest: true},
+	{name: "memprofile", passToTest: true},
+	{name: "memprofilerate", passToTest: true},
+	{name: "blockprofile", passToTest: true},
+	{name: "blockprofilerate", passToTest: true},
+	{name: "outputdir", passToTest: true},
+	{name: "parallel", passToTest: true},
+	{name: "run", passToTest: true},
+	{name: "short", boolVar: new(bool), passToTest: true},
+	{name: "timeout", passToTest: true},
+	{name: "v", boolVar: &testV, passToTest: true},
+}
+
+// testFlags processes the command line, grabbing -x and -c, rewriting known flags
+// to have "test" before them, and reading the command line for the 6.out.
+// Unfortunately for us, we need to do our own flag processing because go test
+// grabs some flags but otherwise its command line is just a holding place for
+// pkg.test's arguments.
+// We allow known flags both before and after the package name list,
+// to allow both
+//	go test fmt -custom-flag-for-fmt-test
+//	go test -x math
+func testFlags(args []string) (packageNames, passToTest []string) {
+	inPkg := false
+	outputDir := ""
+	for i := 0; i < len(args); i++ {
+		if !strings.HasPrefix(args[i], "-") {
+			if !inPkg && packageNames == nil {
+				// First package name we've seen.
+				inPkg = true
+			}
+			if inPkg {
+				packageNames = append(packageNames, args[i])
+				continue
+			}
+		}
+
+		if inPkg {
+			// Found an argument beginning with "-"; end of package list.
+			inPkg = false
+		}
+
+		f, value, extraWord := testFlag(args, i)
+		if f == nil {
+			// This is a flag we do not know; we must assume
+			// that any args we see after this might be flag
+			// arguments, not package names.
+			inPkg = false
+			if packageNames == nil {
+				// make non-nil: we have seen the empty package list
+				packageNames = []string{}
+			}
+			passToTest = append(passToTest, args[i])
+			continue
+		}
+		var err error
+		switch f.name {
+		// bool flags.
+		case "a", "c", "i", "n", "x", "v", "race", "cover", "work":
+			setBoolFlag(f.boolVar, value)
+		case "p":
+			setIntFlag(&buildP, value)
+		case "exec":
+			execCmd, err = splitQuotedFields(value)
+			if err != nil {
+				fatalf("invalid flag argument for -%s: %v", f.name, err)
+			}
+		case "ccflags":
+			buildCcflags, err = splitQuotedFields(value)
+			if err != nil {
+				fatalf("invalid flag argument for -%s: %v", f.name, err)
+			}
+		case "gcflags":
+			buildGcflags, err = splitQuotedFields(value)
+			if err != nil {
+				fatalf("invalid flag argument for -%s: %v", f.name, err)
+			}
+		case "ldflags":
+			buildLdflags, err = splitQuotedFields(value)
+			if err != nil {
+				fatalf("invalid flag argument for -%s: %v", f.name, err)
+			}
+		case "gccgoflags":
+			buildGccgoflags, err = splitQuotedFields(value)
+			if err != nil {
+				fatalf("invalid flag argument for -%s: %v", f.name, err)
+			}
+		case "tags":
+			buildContext.BuildTags = strings.Fields(value)
+		case "compiler":
+			buildCompiler{}.Set(value)
+		case "file":
+			testFiles = append(testFiles, value)
+		case "bench":
+			// record that we saw the flag; don't care about the value
+			testBench = true
+		case "timeout":
+			testTimeout = value
+		case "blockprofile", "cpuprofile", "memprofile":
+			testProfile = true
+			testNeedBinary = true
+		case "coverpkg":
+			testCover = true
+			if value == "" {
+				testCoverPaths = nil
+			} else {
+				testCoverPaths = strings.Split(value, ",")
+			}
+		case "coverprofile":
+			testCover = true
+			testProfile = true
+		case "covermode":
+			switch value {
+			case "set", "count", "atomic":
+				testCoverMode = value
+			default:
+				fatalf("invalid flag argument for -cover: %q", value)
+			}
+			testCover = true
+		case "outputdir":
+			outputDir = value
+		}
+		if extraWord {
+			i++
+		}
+		if f.passToTest {
+			passToTest = append(passToTest, "-test."+f.name+"="+value)
+		}
+	}
+
+	if testCoverMode == "" {
+		testCoverMode = "set"
+		if buildRace {
+			// Default coverage mode is atomic when -race is set.
+			testCoverMode = "atomic"
+		}
+	}
+
+	// Tell the test what directory we're running in, so it can write the profiles there.
+	if testProfile && outputDir == "" {
+		dir, err := os.Getwd()
+		if err != nil {
+			fatalf("error from os.Getwd: %s", err)
+		}
+		passToTest = append(passToTest, "-test.outputdir", dir)
+	}
+	return
+}
+
+// testFlag sees if argument i is a known flag and returns its definition, value, and whether it consumed an extra word.
+func testFlag(args []string, i int) (f *testFlagSpec, value string, extra bool) {
+	arg := args[i]
+	if strings.HasPrefix(arg, "--") { // reduce two minuses to one
+		arg = arg[1:]
+	}
+	switch arg {
+	case "-?", "-h", "-help":
+		usage()
+	}
+	if arg == "" || arg[0] != '-' {
+		return
+	}
+	name := arg[1:]
+	// If there's already "test.", drop it for now.
+	name = strings.TrimPrefix(name, "test.")
+	equals := strings.Index(name, "=")
+	if equals >= 0 {
+		value = name[equals+1:]
+		name = name[:equals]
+	}
+	for _, f = range testFlagDefn {
+		if name == f.name {
+			// Booleans are special because they have modes -x, -x=true, -x=false.
+			if f.boolVar != nil {
+				if equals < 0 { // otherwise, it's been set and will be verified in setBoolFlag
+					value = "true"
+				} else {
+					// verify it parses
+					setBoolFlag(new(bool), value)
+				}
+			} else { // Non-booleans must have a value.
+				extra = equals < 0
+				if extra {
+					if i+1 >= len(args) {
+						testSyntaxError("missing argument for flag " + f.name)
+					}
+					value = args[i+1]
+				}
+			}
+			if f.present && !f.multiOK {
+				testSyntaxError(f.name + " flag may be set only once")
+			}
+			f.present = true
+			return
+		}
+	}
+	f = nil
+	return
+}
+
+// setBoolFlag sets the addressed boolean to the value.
+func setBoolFlag(flag *bool, value string) {
+	x, err := strconv.ParseBool(value)
+	if err != nil {
+		testSyntaxError("illegal bool flag value " + value)
+	}
+	*flag = x
+}
+
+// setIntFlag sets the addressed integer to the value.
+func setIntFlag(flag *int, value string) {
+	x, err := strconv.Atoi(value)
+	if err != nil {
+		testSyntaxError("illegal int flag value " + value)
+	}
+	*flag = x
+}
+
+func testSyntaxError(msg string) {
+	fmt.Fprintf(os.Stderr, "go test: %s\n", msg)
+	fmt.Fprintf(os.Stderr, `run "go help test" or "go help testflag" for more information`+"\n")
+	os.Exit(2)
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/tool.go b/third_party/gofrontend/libgo/go/cmd/go/tool.go
new file mode 100644
index 0000000..6d26f7a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/tool.go
@@ -0,0 +1,156 @@
+// Copyright 2011 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"
+	"go/build"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"sort"
+	"strings"
+)
+
+var cmdTool = &Command{
+	Run:       runTool,
+	UsageLine: "tool [-n] command [args...]",
+	Short:     "run specified go tool",
+	Long: `
+Tool runs the go tool command identified by the arguments.
+With no arguments it prints the list of known tools.
+
+The -n flag causes tool to print the command that would be
+executed but not execute it.
+
+For more about each tool command, see 'go tool command -h'.
+`,
+}
+
+var (
+	toolGOOS      = runtime.GOOS
+	toolGOARCH    = runtime.GOARCH
+	toolIsWindows = toolGOOS == "windows"
+	toolDir       = build.ToolDir
+
+	toolN bool
+)
+
+func init() {
+	cmdTool.Flag.BoolVar(&toolN, "n", false, "")
+}
+
+const toolWindowsExtension = ".exe"
+
+func tool(toolName string) string {
+	toolPath := filepath.Join(toolDir, toolName)
+	if toolIsWindows && toolName != "pprof" {
+		toolPath += toolWindowsExtension
+	}
+	// Give a nice message if there is no tool with that name.
+	if _, err := os.Stat(toolPath); err != nil {
+		if isInGoToolsRepo(toolName) {
+			fmt.Fprintf(os.Stderr, "go tool: no such tool %q; to install:\n\tgo get code.google.com/p/go.tools/cmd/%s\n", toolName, toolName)
+		} else {
+			fmt.Fprintf(os.Stderr, "go tool: no such tool %q\n", toolName)
+		}
+		setExitStatus(3)
+		exit()
+	}
+	return toolPath
+}
+
+func isInGoToolsRepo(toolName string) bool {
+	switch toolName {
+	case "cover", "vet":
+		return true
+	}
+	return false
+}
+
+func runTool(cmd *Command, args []string) {
+	if len(args) == 0 {
+		listTools()
+		return
+	}
+	toolName := args[0]
+	// The tool name must be lower-case letters, numbers or underscores.
+	for _, c := range toolName {
+		switch {
+		case 'a' <= c && c <= 'z', '0' <= c && c <= '9', c == '_':
+		default:
+			fmt.Fprintf(os.Stderr, "go tool: bad tool name %q\n", toolName)
+			setExitStatus(2)
+			return
+		}
+	}
+	toolPath := tool(toolName)
+	if toolPath == "" {
+		return
+	}
+	if toolIsWindows && toolName == "pprof" {
+		args = append([]string{"perl", toolPath}, args[1:]...)
+		var err error
+		toolPath, err = exec.LookPath("perl")
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "go tool: perl not found\n")
+			setExitStatus(3)
+			return
+		}
+	}
+	if toolN {
+		fmt.Printf("%s %s\n", toolPath, strings.Join(args[1:], " "))
+		return
+	}
+	toolCmd := &exec.Cmd{
+		Path:   toolPath,
+		Args:   args,
+		Stdin:  os.Stdin,
+		Stdout: os.Stdout,
+		Stderr: os.Stderr,
+	}
+	err := toolCmd.Run()
+	if err != nil {
+		// Only print about the exit status if the command
+		// didn't even run (not an ExitError) or it didn't exit cleanly
+		// or we're printing command lines too (-x mode).
+		// Assume if command exited cleanly (even with non-zero status)
+		// it printed any messages it wanted to print.
+		if e, ok := err.(*exec.ExitError); !ok || !e.Exited() || buildX {
+			fmt.Fprintf(os.Stderr, "go tool %s: %s\n", toolName, err)
+		}
+		setExitStatus(1)
+		return
+	}
+}
+
+// listTools prints a list of the available tools in the tools directory.
+func listTools() {
+	f, err := os.Open(toolDir)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "go tool: no tool directory: %s\n", err)
+		setExitStatus(2)
+		return
+	}
+	defer f.Close()
+	names, err := f.Readdirnames(-1)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "go tool: can't read directory: %s\n", err)
+		setExitStatus(2)
+		return
+	}
+
+	sort.Strings(names)
+	for _, name := range names {
+		// Unify presentation by going to lower case.
+		name = strings.ToLower(name)
+		// If it's windows, don't show the .exe suffix.
+		if toolIsWindows && strings.HasSuffix(name, toolWindowsExtension) {
+			name = name[:len(name)-len(toolWindowsExtension)]
+		}
+		fmt.Println(name)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/vcs.go b/third_party/gofrontend/libgo/go/cmd/go/vcs.go
new file mode 100644
index 0000000..8f0bae0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/vcs.go
@@ -0,0 +1,728 @@
+// 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 main
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"regexp"
+	"strings"
+)
+
+// A vcsCmd describes how to use a version control system
+// like Mercurial, Git, or Subversion.
+type vcsCmd struct {
+	name string
+	cmd  string // name of binary to invoke command
+
+	createCmd   string // command to download a fresh copy of a repository
+	downloadCmd string // command to download updates into an existing repository
+
+	tagCmd         []tagCmd // commands to list tags
+	tagLookupCmd   []tagCmd // commands to lookup tags before running tagSyncCmd
+	tagSyncCmd     string   // command to sync to specific tag
+	tagSyncDefault string   // command to sync to default tag
+
+	scheme  []string
+	pingCmd string
+}
+
+// A tagCmd describes a command to list available tags
+// that can be passed to tagSyncCmd.
+type tagCmd struct {
+	cmd     string // command to list tags
+	pattern string // regexp to extract tags from list
+}
+
+// vcsList lists the known version control systems
+var vcsList = []*vcsCmd{
+	vcsHg,
+	vcsGit,
+	vcsSvn,
+	vcsBzr,
+}
+
+// vcsByCmd returns the version control system for the given
+// command name (hg, git, svn, bzr).
+func vcsByCmd(cmd string) *vcsCmd {
+	for _, vcs := range vcsList {
+		if vcs.cmd == cmd {
+			return vcs
+		}
+	}
+	return nil
+}
+
+// vcsHg describes how to use Mercurial.
+var vcsHg = &vcsCmd{
+	name: "Mercurial",
+	cmd:  "hg",
+
+	createCmd:   "clone -U {repo} {dir}",
+	downloadCmd: "pull",
+
+	// We allow both tag and branch names as 'tags'
+	// for selecting a version.  This lets people have
+	// a go.release.r60 branch and a go1 branch
+	// and make changes in both, without constantly
+	// editing .hgtags.
+	tagCmd: []tagCmd{
+		{"tags", `^(\S+)`},
+		{"branches", `^(\S+)`},
+	},
+	tagSyncCmd:     "update -r {tag}",
+	tagSyncDefault: "update default",
+
+	scheme:  []string{"https", "http", "ssh"},
+	pingCmd: "identify {scheme}://{repo}",
+}
+
+// vcsGit describes how to use Git.
+var vcsGit = &vcsCmd{
+	name: "Git",
+	cmd:  "git",
+
+	createCmd:   "clone {repo} {dir}",
+	downloadCmd: "pull --ff-only",
+
+	tagCmd: []tagCmd{
+		// tags/xxx matches a git tag named xxx
+		// origin/xxx matches a git branch named xxx on the default remote repository
+		{"show-ref", `(?:tags|origin)/(\S+)$`},
+	},
+	tagLookupCmd: []tagCmd{
+		{"show-ref tags/{tag} origin/{tag}", `((?:tags|origin)/\S+)$`},
+	},
+	tagSyncCmd:     "checkout {tag}",
+	tagSyncDefault: "checkout master",
+
+	scheme:  []string{"git", "https", "http", "git+ssh"},
+	pingCmd: "ls-remote {scheme}://{repo}",
+}
+
+// vcsBzr describes how to use Bazaar.
+var vcsBzr = &vcsCmd{
+	name: "Bazaar",
+	cmd:  "bzr",
+
+	createCmd: "branch {repo} {dir}",
+
+	// Without --overwrite bzr will not pull tags that changed.
+	// Replace by --overwrite-tags after http://pad.lv/681792 goes in.
+	downloadCmd: "pull --overwrite",
+
+	tagCmd:         []tagCmd{{"tags", `^(\S+)`}},
+	tagSyncCmd:     "update -r {tag}",
+	tagSyncDefault: "update -r revno:-1",
+
+	scheme:  []string{"https", "http", "bzr", "bzr+ssh"},
+	pingCmd: "info {scheme}://{repo}",
+}
+
+// vcsSvn describes how to use Subversion.
+var vcsSvn = &vcsCmd{
+	name: "Subversion",
+	cmd:  "svn",
+
+	createCmd:   "checkout {repo} {dir}",
+	downloadCmd: "update",
+
+	// There is no tag command in subversion.
+	// The branch information is all in the path names.
+
+	scheme:  []string{"https", "http", "svn", "svn+ssh"},
+	pingCmd: "info {scheme}://{repo}",
+}
+
+func (v *vcsCmd) String() string {
+	return v.name
+}
+
+// run runs the command line cmd in the given directory.
+// keyval is a list of key, value pairs.  run expands
+// instances of {key} in cmd into value, but only after
+// splitting cmd into individual arguments.
+// If an error occurs, run prints the command line and the
+// command's combined stdout+stderr to standard error.
+// Otherwise run discards the command's output.
+func (v *vcsCmd) run(dir string, cmd string, keyval ...string) error {
+	_, err := v.run1(dir, cmd, keyval, true)
+	return err
+}
+
+// runVerboseOnly is like run but only generates error output to standard error in verbose mode.
+func (v *vcsCmd) runVerboseOnly(dir string, cmd string, keyval ...string) error {
+	_, err := v.run1(dir, cmd, keyval, false)
+	return err
+}
+
+// runOutput is like run but returns the output of the command.
+func (v *vcsCmd) runOutput(dir string, cmd string, keyval ...string) ([]byte, error) {
+	return v.run1(dir, cmd, keyval, true)
+}
+
+// run1 is the generalized implementation of run and runOutput.
+func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool) ([]byte, error) {
+	m := make(map[string]string)
+	for i := 0; i < len(keyval); i += 2 {
+		m[keyval[i]] = keyval[i+1]
+	}
+	args := strings.Fields(cmdline)
+	for i, arg := range args {
+		args[i] = expand(m, arg)
+	}
+
+	_, err := exec.LookPath(v.cmd)
+	if err != nil {
+		fmt.Fprintf(os.Stderr,
+			"go: missing %s command. See http://golang.org/s/gogetcmd\n",
+			v.name)
+		return nil, err
+	}
+
+	cmd := exec.Command(v.cmd, args...)
+	cmd.Dir = dir
+	cmd.Env = envForDir(cmd.Dir)
+	if buildX {
+		fmt.Printf("cd %s\n", dir)
+		fmt.Printf("%s %s\n", v.cmd, strings.Join(args, " "))
+	}
+	var buf bytes.Buffer
+	cmd.Stdout = &buf
+	cmd.Stderr = &buf
+	err = cmd.Run()
+	out := buf.Bytes()
+	if err != nil {
+		if verbose || buildV {
+			fmt.Fprintf(os.Stderr, "# cd %s; %s %s\n", dir, v.cmd, strings.Join(args, " "))
+			os.Stderr.Write(out)
+		}
+		return nil, err
+	}
+	return out, nil
+}
+
+// ping pings to determine scheme to use.
+func (v *vcsCmd) ping(scheme, repo string) error {
+	return v.runVerboseOnly(".", v.pingCmd, "scheme", scheme, "repo", repo)
+}
+
+// create creates a new copy of repo in dir.
+// The parent of dir must exist; dir must not.
+func (v *vcsCmd) create(dir, repo string) error {
+	return v.run(".", v.createCmd, "dir", dir, "repo", repo)
+}
+
+// download downloads any new changes for the repo in dir.
+func (v *vcsCmd) download(dir string) error {
+	if err := v.fixDetachedHead(dir); err != nil {
+		return err
+	}
+	return v.run(dir, v.downloadCmd)
+}
+
+// fixDetachedHead switches a Git repository in dir from a detached head to the master branch.
+// Go versions before 1.2 downloaded Git repositories in an unfortunate way
+// that resulted in the working tree state being on a detached head.
+// That meant the repository was not usable for normal Git operations.
+// Go 1.2 fixed that, but we can't pull into a detached head, so if this is
+// a Git repository we check for being on a detached head and switch to the
+// real branch, almost always called "master".
+// TODO(dsymonds): Consider removing this for Go 1.3.
+func (v *vcsCmd) fixDetachedHead(dir string) error {
+	if v != vcsGit {
+		return nil
+	}
+
+	// "git symbolic-ref HEAD" succeeds iff we are not on a detached head.
+	if err := v.runVerboseOnly(dir, "symbolic-ref HEAD"); err == nil {
+		// not on a detached head
+		return nil
+	}
+	if buildV {
+		log.Printf("%s on detached head; repairing", dir)
+	}
+	return v.run(dir, "checkout master")
+}
+
+// tags returns the list of available tags for the repo in dir.
+func (v *vcsCmd) tags(dir string) ([]string, error) {
+	var tags []string
+	for _, tc := range v.tagCmd {
+		out, err := v.runOutput(dir, tc.cmd)
+		if err != nil {
+			return nil, err
+		}
+		re := regexp.MustCompile(`(?m-s)` + tc.pattern)
+		for _, m := range re.FindAllStringSubmatch(string(out), -1) {
+			tags = append(tags, m[1])
+		}
+	}
+	return tags, nil
+}
+
+// tagSync syncs the repo in dir to the named tag,
+// which either is a tag returned by tags or is v.tagDefault.
+func (v *vcsCmd) tagSync(dir, tag string) error {
+	if v.tagSyncCmd == "" {
+		return nil
+	}
+	if tag != "" {
+		for _, tc := range v.tagLookupCmd {
+			out, err := v.runOutput(dir, tc.cmd, "tag", tag)
+			if err != nil {
+				return err
+			}
+			re := regexp.MustCompile(`(?m-s)` + tc.pattern)
+			m := re.FindStringSubmatch(string(out))
+			if len(m) > 1 {
+				tag = m[1]
+				break
+			}
+		}
+	}
+	if tag == "" && v.tagSyncDefault != "" {
+		return v.run(dir, v.tagSyncDefault)
+	}
+	return v.run(dir, v.tagSyncCmd, "tag", tag)
+}
+
+// A vcsPath describes how to convert an import path into a
+// version control system and repository name.
+type vcsPath struct {
+	prefix string                              // prefix this description applies to
+	re     string                              // pattern for import path
+	repo   string                              // repository to use (expand with match of re)
+	vcs    string                              // version control system to use (expand with match of re)
+	check  func(match map[string]string) error // additional checks
+	ping   bool                                // ping for scheme to use to download repo
+
+	regexp *regexp.Regexp // cached compiled form of re
+}
+
+// vcsForDir inspects dir and its parents to determine the
+// version control system and code repository to use.
+// On return, root is the import path
+// corresponding to the root of the repository
+// (thus root is a prefix of importPath).
+func vcsForDir(p *Package) (vcs *vcsCmd, root string, err error) {
+	// Clean and double-check that dir is in (a subdirectory of) srcRoot.
+	dir := filepath.Clean(p.Dir)
+	srcRoot := filepath.Clean(p.build.SrcRoot)
+	if len(dir) <= len(srcRoot) || dir[len(srcRoot)] != filepath.Separator {
+		return nil, "", fmt.Errorf("directory %q is outside source root %q", dir, srcRoot)
+	}
+
+	origDir := dir
+	for len(dir) > len(srcRoot) {
+		for _, vcs := range vcsList {
+			if fi, err := os.Stat(filepath.Join(dir, "."+vcs.cmd)); err == nil && fi.IsDir() {
+				return vcs, dir[len(srcRoot)+1:], nil
+			}
+		}
+
+		// Move to parent.
+		ndir := filepath.Dir(dir)
+		if len(ndir) >= len(dir) {
+			// Shouldn't happen, but just in case, stop.
+			break
+		}
+		dir = ndir
+	}
+
+	return nil, "", fmt.Errorf("directory %q is not using a known version control system", origDir)
+}
+
+// repoRoot represents a version control system, a repo, and a root of
+// where to put it on disk.
+type repoRoot struct {
+	vcs *vcsCmd
+
+	// repo is the repository URL, including scheme
+	repo string
+
+	// root is the import path corresponding to the root of the
+	// repository
+	root string
+}
+
+var httpPrefixRE = regexp.MustCompile(`^https?:`)
+
+// repoRootForImportPath analyzes importPath to determine the
+// version control system, and code repository to use.
+func repoRootForImportPath(importPath string) (*repoRoot, error) {
+	rr, err := repoRootForImportPathStatic(importPath, "")
+	if err == errUnknownSite {
+		rr, err = repoRootForImportDynamic(importPath)
+
+		// repoRootForImportDynamic returns error detail
+		// that is irrelevant if the user didn't intend to use a
+		// dynamic import in the first place.
+		// Squelch it.
+		if err != nil {
+			if buildV {
+				log.Printf("import %q: %v", importPath, err)
+			}
+			err = fmt.Errorf("unrecognized import path %q", importPath)
+		}
+	}
+
+	if err == nil && strings.Contains(importPath, "...") && strings.Contains(rr.root, "...") {
+		// Do not allow wildcards in the repo root.
+		rr = nil
+		err = fmt.Errorf("cannot expand ... in %q", importPath)
+	}
+	return rr, err
+}
+
+var errUnknownSite = errors.New("dynamic lookup required to find mapping")
+
+// repoRootForImportPathStatic attempts to map importPath to a
+// repoRoot using the commonly-used VCS hosting sites in vcsPaths
+// (github.com/user/dir), or from a fully-qualified importPath already
+// containing its VCS type (foo.com/repo.git/dir)
+//
+// If scheme is non-empty, that scheme is forced.
+func repoRootForImportPathStatic(importPath, scheme string) (*repoRoot, error) {
+	// A common error is to use https://packagepath because that's what
+	// hg and git require. Diagnose this helpfully.
+	if loc := httpPrefixRE.FindStringIndex(importPath); loc != nil {
+		// The importPath has been cleaned, so has only one slash. The pattern
+		// ignores the slashes; the error message puts them back on the RHS at least.
+		return nil, fmt.Errorf("%q not allowed in import path", importPath[loc[0]:loc[1]]+"//")
+	}
+	for _, srv := range vcsPaths {
+		if !strings.HasPrefix(importPath, srv.prefix) {
+			continue
+		}
+		m := srv.regexp.FindStringSubmatch(importPath)
+		if m == nil {
+			if srv.prefix != "" {
+				return nil, fmt.Errorf("invalid %s import path %q", srv.prefix, importPath)
+			}
+			continue
+		}
+
+		// Build map of named subexpression matches for expand.
+		match := map[string]string{
+			"prefix": srv.prefix,
+			"import": importPath,
+		}
+		for i, name := range srv.regexp.SubexpNames() {
+			if name != "" && match[name] == "" {
+				match[name] = m[i]
+			}
+		}
+		if srv.vcs != "" {
+			match["vcs"] = expand(match, srv.vcs)
+		}
+		if srv.repo != "" {
+			match["repo"] = expand(match, srv.repo)
+		}
+		if srv.check != nil {
+			if err := srv.check(match); err != nil {
+				return nil, err
+			}
+		}
+		vcs := vcsByCmd(match["vcs"])
+		if vcs == nil {
+			return nil, fmt.Errorf("unknown version control system %q", match["vcs"])
+		}
+		if srv.ping {
+			if scheme != "" {
+				match["repo"] = scheme + "://" + match["repo"]
+			} else {
+				for _, scheme := range vcs.scheme {
+					if vcs.ping(scheme, match["repo"]) == nil {
+						match["repo"] = scheme + "://" + match["repo"]
+						break
+					}
+				}
+			}
+		}
+		rr := &repoRoot{
+			vcs:  vcs,
+			repo: match["repo"],
+			root: match["root"],
+		}
+		return rr, nil
+	}
+	return nil, errUnknownSite
+}
+
+// repoRootForImportDynamic finds a *repoRoot for a custom domain that's not
+// statically known by repoRootForImportPathStatic.
+//
+// This handles "vanity import paths" like "name.tld/pkg/foo".
+func repoRootForImportDynamic(importPath string) (*repoRoot, error) {
+	slash := strings.Index(importPath, "/")
+	if slash < 0 {
+		return nil, errors.New("import path doesn't contain a slash")
+	}
+	host := importPath[:slash]
+	if !strings.Contains(host, ".") {
+		return nil, errors.New("import path doesn't contain a hostname")
+	}
+	urlStr, body, err := httpsOrHTTP(importPath)
+	if err != nil {
+		return nil, fmt.Errorf("http/https fetch: %v", err)
+	}
+	defer body.Close()
+	imports, err := parseMetaGoImports(body)
+	if err != nil {
+		return nil, fmt.Errorf("parsing %s: %v", importPath, err)
+	}
+	metaImport, err := matchGoImport(imports, importPath)
+	if err != nil {
+		if err != errNoMatch {
+			return nil, fmt.Errorf("parse %s: %v", urlStr, err)
+		}
+		return nil, fmt.Errorf("parse %s: no go-import meta tags", urlStr)
+	}
+	if buildV {
+		log.Printf("get %q: found meta tag %#v at %s", importPath, metaImport, urlStr)
+	}
+	// If the import was "uni.edu/bob/project", which said the
+	// prefix was "uni.edu" and the RepoRoot was "evilroot.com",
+	// make sure we don't trust Bob and check out evilroot.com to
+	// "uni.edu" yet (possibly overwriting/preempting another
+	// non-evil student).  Instead, first verify the root and see
+	// if it matches Bob's claim.
+	if metaImport.Prefix != importPath {
+		if buildV {
+			log.Printf("get %q: verifying non-authoritative meta tag", importPath)
+		}
+		urlStr0 := urlStr
+		urlStr, body, err = httpsOrHTTP(metaImport.Prefix)
+		if err != nil {
+			return nil, fmt.Errorf("fetch %s: %v", urlStr, err)
+		}
+		imports, err := parseMetaGoImports(body)
+		if err != nil {
+			return nil, fmt.Errorf("parsing %s: %v", importPath, err)
+		}
+		if len(imports) == 0 {
+			return nil, fmt.Errorf("fetch %s: no go-import meta tag", urlStr)
+		}
+		metaImport2, err := matchGoImport(imports, importPath)
+		if err != nil || metaImport != metaImport2 {
+			return nil, fmt.Errorf("%s and %s disagree about go-import for %s", urlStr0, urlStr, metaImport.Prefix)
+		}
+	}
+
+	if !strings.Contains(metaImport.RepoRoot, "://") {
+		return nil, fmt.Errorf("%s: invalid repo root %q; no scheme", urlStr, metaImport.RepoRoot)
+	}
+	rr := &repoRoot{
+		vcs:  vcsByCmd(metaImport.VCS),
+		repo: metaImport.RepoRoot,
+		root: metaImport.Prefix,
+	}
+	if rr.vcs == nil {
+		return nil, fmt.Errorf("%s: unknown vcs %q", urlStr, metaImport.VCS)
+	}
+	return rr, nil
+}
+
+// metaImport represents the parsed <meta name="go-import"
+// content="prefix vcs reporoot" /> tags from HTML files.
+type metaImport struct {
+	Prefix, VCS, RepoRoot string
+}
+
+// errNoMatch is returned from matchGoImport when there's no applicable match.
+var errNoMatch = errors.New("no import match")
+
+// matchGoImport returns the metaImport from imports matching importPath.
+// An error is returned if there are multiple matches.
+// errNoMatch is returned if none match.
+func matchGoImport(imports []metaImport, importPath string) (_ metaImport, err error) {
+	match := -1
+	for i, im := range imports {
+		if !strings.HasPrefix(importPath, im.Prefix) {
+			continue
+		}
+		if match != -1 {
+			err = fmt.Errorf("multiple meta tags match import path %q", importPath)
+			return
+		}
+		match = i
+	}
+	if match == -1 {
+		err = errNoMatch
+		return
+	}
+	return imports[match], nil
+}
+
+// expand rewrites s to replace {k} with match[k] for each key k in match.
+func expand(match map[string]string, s string) string {
+	for k, v := range match {
+		s = strings.Replace(s, "{"+k+"}", v, -1)
+	}
+	return s
+}
+
+// vcsPaths lists the known vcs paths.
+var vcsPaths = []*vcsPath{
+	// Google Code - new syntax
+	{
+		prefix: "code.google.com/",
+		re:     `^(?P<root>code\.google\.com/p/(?P<project>[a-z0-9\-]+)(\.(?P<subrepo>[a-z0-9\-]+))?)(/[A-Za-z0-9_.\-]+)*$`,
+		repo:   "https://{root}",
+		check:  googleCodeVCS,
+	},
+
+	// Google Code - old syntax
+	{
+		re:    `^(?P<project>[a-z0-9_\-.]+)\.googlecode\.com/(git|hg|svn)(?P<path>/.*)?$`,
+		check: oldGoogleCode,
+	},
+
+	// Github
+	{
+		prefix: "github.com/",
+		re:     `^(?P<root>github\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`,
+		vcs:    "git",
+		repo:   "https://{root}",
+		check:  noVCSSuffix,
+	},
+
+	// Bitbucket
+	{
+		prefix: "bitbucket.org/",
+		re:     `^(?P<root>bitbucket\.org/(?P<bitname>[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`,
+		repo:   "https://{root}",
+		check:  bitbucketVCS,
+	},
+
+	// Launchpad
+	{
+		prefix: "launchpad.net/",
+		re:     `^(?P<root>launchpad\.net/((?P<project>[A-Za-z0-9_.\-]+)(?P<series>/[A-Za-z0-9_.\-]+)?|~[A-Za-z0-9_.\-]+/(\+junk|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`,
+		vcs:    "bzr",
+		repo:   "https://{root}",
+		check:  launchpadVCS,
+	},
+
+	// General syntax for any server.
+	{
+		re:   `^(?P<root>(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?/[A-Za-z0-9_.\-/]*?)\.(?P<vcs>bzr|git|hg|svn))(/[A-Za-z0-9_.\-]+)*$`,
+		ping: true,
+	},
+}
+
+func init() {
+	// fill in cached regexps.
+	// Doing this eagerly discovers invalid regexp syntax
+	// without having to run a command that needs that regexp.
+	for _, srv := range vcsPaths {
+		srv.regexp = regexp.MustCompile(srv.re)
+	}
+}
+
+// noVCSSuffix checks that the repository name does not
+// end in .foo for any version control system foo.
+// The usual culprit is ".git".
+func noVCSSuffix(match map[string]string) error {
+	repo := match["repo"]
+	for _, vcs := range vcsList {
+		if strings.HasSuffix(repo, "."+vcs.cmd) {
+			return fmt.Errorf("invalid version control suffix in %s path", match["prefix"])
+		}
+	}
+	return nil
+}
+
+var googleCheckout = regexp.MustCompile(`id="checkoutcmd">(hg|git|svn)`)
+
+// googleCodeVCS determines the version control system for
+// a code.google.com repository, by scraping the project's
+// /source/checkout page.
+func googleCodeVCS(match map[string]string) error {
+	if err := noVCSSuffix(match); err != nil {
+		return err
+	}
+	data, err := httpGET(expand(match, "https://code.google.com/p/{project}/source/checkout?repo={subrepo}"))
+	if err != nil {
+		return err
+	}
+
+	if m := googleCheckout.FindSubmatch(data); m != nil {
+		if vcs := vcsByCmd(string(m[1])); vcs != nil {
+			// Subversion requires the old URLs.
+			// TODO: Test.
+			if vcs == vcsSvn {
+				if match["subrepo"] != "" {
+					return fmt.Errorf("sub-repositories not supported in Google Code Subversion projects")
+				}
+				match["repo"] = expand(match, "https://{project}.googlecode.com/svn")
+			}
+			match["vcs"] = vcs.cmd
+			return nil
+		}
+	}
+
+	return fmt.Errorf("unable to detect version control system for code.google.com/ path")
+}
+
+// oldGoogleCode is invoked for old-style foo.googlecode.com paths.
+// It prints an error giving the equivalent new path.
+func oldGoogleCode(match map[string]string) error {
+	return fmt.Errorf("invalid Google Code import path: use %s instead",
+		expand(match, "code.google.com/p/{project}{path}"))
+}
+
+// bitbucketVCS determines the version control system for a
+// Bitbucket repository, by using the Bitbucket API.
+func bitbucketVCS(match map[string]string) error {
+	if err := noVCSSuffix(match); err != nil {
+		return err
+	}
+
+	var resp struct {
+		SCM string `json:"scm"`
+	}
+	url := expand(match, "https://api.bitbucket.org/1.0/repositories/{bitname}")
+	data, err := httpGET(url)
+	if err != nil {
+		return err
+	}
+	if err := json.Unmarshal(data, &resp); err != nil {
+		return fmt.Errorf("decoding %s: %v", url, err)
+	}
+
+	if vcsByCmd(resp.SCM) != nil {
+		match["vcs"] = resp.SCM
+		if resp.SCM == "git" {
+			match["repo"] += ".git"
+		}
+		return nil
+	}
+
+	return fmt.Errorf("unable to detect version control system for bitbucket.org/ path")
+}
+
+// launchpadVCS solves the ambiguity for "lp.net/project/foo". In this case,
+// "foo" could be a series name registered in Launchpad with its own branch,
+// and it could also be the name of a directory within the main project
+// branch one level up.
+func launchpadVCS(match map[string]string) error {
+	if match["project"] == "" || match["series"] == "" {
+		return nil
+	}
+	_, err := httpGET(expand(match, "https://code.launchpad.net/{project}{series}/.bzr/branch-format"))
+	if err != nil {
+		match["root"] = expand(match, "launchpad.net/{project}")
+		match["repo"] = expand(match, "https://{root}")
+	}
+	return nil
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/version.go b/third_party/gofrontend/libgo/go/cmd/go/version.go
new file mode 100644
index 0000000..a41f4a7
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/version.go
@@ -0,0 +1,25 @@
+// Copyright 2011 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"
+	"runtime"
+)
+
+var cmdVersion = &Command{
+	Run:       runVersion,
+	UsageLine: "version",
+	Short:     "print Go version",
+	Long:      `Version prints the Go version, as reported by runtime.Version.`,
+}
+
+func runVersion(cmd *Command, args []string) {
+	if len(args) != 0 {
+		cmd.Usage()
+	}
+
+	fmt.Printf("go version %s %s/%s\n", runtime.Version(), runtime.GOOS, runtime.GOARCH)
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/go/vet.go b/third_party/gofrontend/libgo/go/cmd/go/vet.go
new file mode 100644
index 0000000..ffb4318
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/go/vet.go
@@ -0,0 +1,37 @@
+// Copyright 2011 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
+
+func init() {
+	addBuildFlagsNX(cmdVet)
+}
+
+var cmdVet = &Command{
+	Run:       runVet,
+	UsageLine: "vet [-n] [-x] [packages]",
+	Short:     "run go tool vet on packages",
+	Long: `
+Vet runs the Go vet command on the packages named by the import paths.
+
+For more about vet, see 'godoc code.google.com/p/go.tools/cmd/vet'.
+For more about specifying packages, see 'go help packages'.
+
+To run the vet tool with specific options, run 'go tool vet'.
+
+The -n flag prints commands that would be executed.
+The -x flag prints commands as they are executed.
+
+See also: go fmt, go fix.
+	`,
+}
+
+func runVet(cmd *Command, args []string) {
+	for _, pkg := range packages(args) {
+		// Use pkg.gofiles instead of pkg.Dir so that
+		// the command only applies to this package,
+		// not to packages in subdirectories.
+		run(tool("vet"), relPaths(stringList(pkg.gofiles, pkg.sfiles)))
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/doc.go b/third_party/gofrontend/libgo/go/cmd/gofmt/doc.go
new file mode 100644
index 0000000..8f73ef5
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/doc.go
@@ -0,0 +1,93 @@
+// 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.
+
+/*
+Gofmt formats Go programs.
+It uses tabs (width = 8) for indentation and blanks for alignment.
+
+Without an explicit path, it processes the standard input.  Given a file,
+it operates on that file; given a directory, it operates on all .go files in
+that directory, recursively.  (Files starting with a period are ignored.)
+By default, gofmt prints the reformatted sources to standard output.
+
+Usage:
+	gofmt [flags] [path ...]
+
+The flags are:
+	-d
+		Do not print reformatted sources to standard output.
+		If a file's formatting is different than gofmt's, print diffs
+		to standard output.
+	-e
+		Print all (including spurious) errors.
+	-l
+		Do not print reformatted sources to standard output.
+		If a file's formatting is different from gofmt's, print its name
+		to standard output.
+	-r rule
+		Apply the rewrite rule to the source before reformatting.
+	-s
+		Try to simplify code (after applying the rewrite rule, if any).
+	-w
+		Do not print reformatted sources to standard output.
+		If a file's formatting is different from gofmt's, overwrite it
+		with gofmt's version.
+
+Debugging support:
+	-cpuprofile filename
+		Write cpu profile to the specified file.
+
+
+The rewrite rule specified with the -r flag must be a string of the form:
+
+	pattern -> replacement
+
+Both pattern and replacement must be valid Go expressions.
+In the pattern, single-character lowercase identifiers serve as
+wildcards matching arbitrary sub-expressions; those expressions
+will be substituted for the same identifiers in the replacement.
+
+When gofmt reads from standard input, it accepts either a full Go program
+or a program fragment.  A program fragment must be a syntactically
+valid declaration list, statement list, or expression.  When formatting
+such a fragment, gofmt preserves leading indentation as well as leading
+and trailing spaces, so that individual sections of a Go program can be
+formatted by piping them through gofmt.
+
+Examples
+
+To check files for unnecessary parentheses:
+
+	gofmt -r '(a) -> a' -l *.go
+
+To remove the parentheses:
+
+	gofmt -r '(a) -> a' -w *.go
+
+To convert the package tree from explicit slice upper bounds to implicit ones:
+
+	gofmt -r 'α[β:len(α)] -> α[β:]' -w $GOROOT/src/pkg
+
+The simplify command
+
+When invoked with -s gofmt will make the following source transformations where possible.
+
+	An array, slice, or map composite literal of the form:
+		[]T{T{}, T{}}
+	will be simplified to:
+		[]T{{}, {}}
+
+	A slice expression of the form:
+		s[a:len(s)]
+	will be simplified to:
+		s[a:]
+
+	A range of the form:
+		for x, _ = range v {...}
+	will be simplified to:
+		for x = range v {...}
+*/
+package main
+
+// BUG(rsc): The implementation of -r is a bit slow.
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/gofmt.go b/third_party/gofrontend/libgo/go/cmd/gofmt/gofmt.go
new file mode 100644
index 0000000..576cae5
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/gofmt.go
@@ -0,0 +1,344 @@
+// 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 main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/printer"
+	"go/scanner"
+	"go/token"
+	"io"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime/pprof"
+	"strings"
+)
+
+var (
+	// main operation modes
+	list        = flag.Bool("l", false, "list files whose formatting differs from gofmt's")
+	write       = flag.Bool("w", false, "write result to (source) file instead of stdout")
+	rewriteRule = flag.String("r", "", "rewrite rule (e.g., 'a[b:len(a)] -> a[b:]')")
+	simplifyAST = flag.Bool("s", false, "simplify code")
+	doDiff      = flag.Bool("d", false, "display diffs instead of rewriting files")
+	allErrors   = flag.Bool("e", false, "report all errors (not just the first 10 on different lines)")
+
+	// debugging
+	cpuprofile = flag.String("cpuprofile", "", "write cpu profile to this file")
+)
+
+const (
+	tabWidth    = 8
+	printerMode = printer.UseSpaces | printer.TabIndent
+)
+
+var (
+	fileSet    = token.NewFileSet() // per process FileSet
+	exitCode   = 0
+	rewrite    func(*ast.File) *ast.File
+	parserMode parser.Mode
+)
+
+func report(err error) {
+	scanner.PrintError(os.Stderr, err)
+	exitCode = 2
+}
+
+func usage() {
+	fmt.Fprintf(os.Stderr, "usage: gofmt [flags] [path ...]\n")
+	flag.PrintDefaults()
+	os.Exit(2)
+}
+
+func initParserMode() {
+	parserMode = parser.ParseComments
+	if *allErrors {
+		parserMode |= parser.AllErrors
+	}
+}
+
+func isGoFile(f os.FileInfo) bool {
+	// ignore non-Go files
+	name := f.Name()
+	return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
+}
+
+// If in == nil, the source is the contents of the file with the given filename.
+func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error {
+	if in == nil {
+		f, err := os.Open(filename)
+		if err != nil {
+			return err
+		}
+		defer f.Close()
+		in = f
+	}
+
+	src, err := ioutil.ReadAll(in)
+	if err != nil {
+		return err
+	}
+
+	file, adjust, err := parse(fileSet, filename, src, stdin)
+	if err != nil {
+		return err
+	}
+
+	if rewrite != nil {
+		if adjust == nil {
+			file = rewrite(file)
+		} else {
+			fmt.Fprintf(os.Stderr, "warning: rewrite ignored for incomplete programs\n")
+		}
+	}
+
+	ast.SortImports(fileSet, file)
+
+	if *simplifyAST {
+		simplify(file)
+	}
+
+	var buf bytes.Buffer
+	err = (&printer.Config{Mode: printerMode, Tabwidth: tabWidth}).Fprint(&buf, fileSet, file)
+	if err != nil {
+		return err
+	}
+	res := buf.Bytes()
+	if adjust != nil {
+		res = adjust(src, res)
+	}
+
+	if !bytes.Equal(src, res) {
+		// formatting has changed
+		if *list {
+			fmt.Fprintln(out, filename)
+		}
+		if *write {
+			err = ioutil.WriteFile(filename, res, 0)
+			if err != nil {
+				return err
+			}
+		}
+		if *doDiff {
+			data, err := diff(src, res)
+			if err != nil {
+				return fmt.Errorf("computing diff: %s", err)
+			}
+			fmt.Printf("diff %s gofmt/%s\n", filename, filename)
+			out.Write(data)
+		}
+	}
+
+	if !*list && !*write && !*doDiff {
+		_, err = out.Write(res)
+	}
+
+	return err
+}
+
+func visitFile(path string, f os.FileInfo, err error) error {
+	if err == nil && isGoFile(f) {
+		err = processFile(path, nil, os.Stdout, false)
+	}
+	if err != nil {
+		report(err)
+	}
+	return nil
+}
+
+func walkDir(path string) {
+	filepath.Walk(path, visitFile)
+}
+
+func main() {
+	// call gofmtMain in a separate function
+	// so that it can use defer and have them
+	// run before the exit.
+	gofmtMain()
+	os.Exit(exitCode)
+}
+
+func gofmtMain() {
+	flag.Usage = usage
+	flag.Parse()
+
+	if *cpuprofile != "" {
+		f, err := os.Create(*cpuprofile)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "creating cpu profile: %s\n", err)
+			exitCode = 2
+			return
+		}
+		defer f.Close()
+		pprof.StartCPUProfile(f)
+		defer pprof.StopCPUProfile()
+	}
+
+	initParserMode()
+	initRewrite()
+
+	if flag.NArg() == 0 {
+		if err := processFile("<standard input>", os.Stdin, os.Stdout, true); err != nil {
+			report(err)
+		}
+		return
+	}
+
+	for i := 0; i < flag.NArg(); i++ {
+		path := flag.Arg(i)
+		switch dir, err := os.Stat(path); {
+		case err != nil:
+			report(err)
+		case dir.IsDir():
+			walkDir(path)
+		default:
+			if err := processFile(path, nil, os.Stdout, false); err != nil {
+				report(err)
+			}
+		}
+	}
+}
+
+func diff(b1, b2 []byte) (data []byte, err error) {
+	f1, err := ioutil.TempFile("", "gofmt")
+	if err != nil {
+		return
+	}
+	defer os.Remove(f1.Name())
+	defer f1.Close()
+
+	f2, err := ioutil.TempFile("", "gofmt")
+	if err != nil {
+		return
+	}
+	defer os.Remove(f2.Name())
+	defer f2.Close()
+
+	f1.Write(b1)
+	f2.Write(b2)
+
+	data, err = exec.Command("diff", "-u", f1.Name(), f2.Name()).CombinedOutput()
+	if len(data) > 0 {
+		// diff exits with a non-zero status when the files don't match.
+		// Ignore that failure as long as we get output.
+		err = nil
+	}
+	return
+
+}
+
+// parse parses src, which was read from filename,
+// as a Go source file or statement list.
+func parse(fset *token.FileSet, filename string, src []byte, stdin bool) (*ast.File, func(orig, src []byte) []byte, error) {
+	// Try as whole source file.
+	file, err := parser.ParseFile(fset, filename, src, parserMode)
+	if err == nil {
+		return file, nil, nil
+	}
+	// If the error is that the source file didn't begin with a
+	// package line and this is standard input, fall through to
+	// try as a source fragment.  Stop and return on any other error.
+	if !stdin || !strings.Contains(err.Error(), "expected 'package'") {
+		return nil, nil, err
+	}
+
+	// If this is a declaration list, make it a source file
+	// by inserting a package clause.
+	// Insert using a ;, not a newline, so that the line numbers
+	// in psrc match the ones in src.
+	psrc := append([]byte("package p;"), src...)
+	file, err = parser.ParseFile(fset, filename, psrc, parserMode)
+	if err == nil {
+		adjust := func(orig, src []byte) []byte {
+			// Remove the package clause.
+			// Gofmt has turned the ; into a \n.
+			src = src[len("package p\n"):]
+			return matchSpace(orig, src)
+		}
+		return file, adjust, nil
+	}
+	// If the error is that the source file didn't begin with a
+	// declaration, fall through to try as a statement list.
+	// Stop and return on any other error.
+	if !strings.Contains(err.Error(), "expected declaration") {
+		return nil, nil, err
+	}
+
+	// If this is a statement list, make it a source file
+	// by inserting a package clause and turning the list
+	// into a function body.  This handles expressions too.
+	// Insert using a ;, not a newline, so that the line numbers
+	// in fsrc match the ones in src.
+	fsrc := append(append([]byte("package p; func _() {"), src...), '}')
+	file, err = parser.ParseFile(fset, filename, fsrc, parserMode)
+	if err == nil {
+		adjust := func(orig, src []byte) []byte {
+			// Remove the wrapping.
+			// Gofmt has turned the ; into a \n\n.
+			src = src[len("package p\n\nfunc _() {"):]
+			src = src[:len(src)-len("}\n")]
+			// Gofmt has also indented the function body one level.
+			// Remove that indent.
+			src = bytes.Replace(src, []byte("\n\t"), []byte("\n"), -1)
+			return matchSpace(orig, src)
+		}
+		return file, adjust, nil
+	}
+
+	// Failed, and out of options.
+	return nil, nil, err
+}
+
+func cutSpace(b []byte) (before, middle, after []byte) {
+	i := 0
+	for i < len(b) && (b[i] == ' ' || b[i] == '\t' || b[i] == '\n') {
+		i++
+	}
+	j := len(b)
+	for j > 0 && (b[j-1] == ' ' || b[j-1] == '\t' || b[j-1] == '\n') {
+		j--
+	}
+	if i <= j {
+		return b[:i], b[i:j], b[j:]
+	}
+	return nil, nil, b[j:]
+}
+
+// matchSpace reformats src to use the same space context as orig.
+// 1) If orig begins with blank lines, matchSpace inserts them at the beginning of src.
+// 2) matchSpace copies the indentation of the first non-blank line in orig
+//    to every non-blank line in src.
+// 3) matchSpace copies the trailing space from orig and uses it in place
+//   of src's trailing space.
+func matchSpace(orig []byte, src []byte) []byte {
+	before, _, after := cutSpace(orig)
+	i := bytes.LastIndex(before, []byte{'\n'})
+	before, indent := before[:i+1], before[i+1:]
+
+	_, src, _ = cutSpace(src)
+
+	var b bytes.Buffer
+	b.Write(before)
+	for len(src) > 0 {
+		line := src
+		if i := bytes.IndexByte(line, '\n'); i >= 0 {
+			line, src = line[:i+1], line[i+1:]
+		} else {
+			src = nil
+		}
+		if len(line) > 0 && line[0] != '\n' { // not blank
+			b.Write(indent)
+		}
+		b.Write(line)
+	}
+	b.Write(after)
+	return b.Bytes()
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/gofmt_test.go b/third_party/gofrontend/libgo/go/cmd/gofmt/gofmt_test.go
new file mode 100644
index 0000000..b9335b8
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/gofmt_test.go
@@ -0,0 +1,134 @@
+// Copyright 2011 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 (
+	"bytes"
+	"io/ioutil"
+	"path/filepath"
+	"strings"
+	"testing"
+)
+
+func runTest(t *testing.T, in, out, flags string) {
+	// process flags
+	*simplifyAST = false
+	*rewriteRule = ""
+	stdin := false
+	for _, flag := range strings.Split(flags, " ") {
+		elts := strings.SplitN(flag, "=", 2)
+		name := elts[0]
+		value := ""
+		if len(elts) == 2 {
+			value = elts[1]
+		}
+		switch name {
+		case "":
+			// no flags
+		case "-r":
+			*rewriteRule = value
+		case "-s":
+			*simplifyAST = true
+		case "-stdin":
+			// fake flag - pretend input is from stdin
+			stdin = true
+		default:
+			t.Errorf("unrecognized flag name: %s", name)
+		}
+	}
+
+	initParserMode()
+	initRewrite()
+
+	var buf bytes.Buffer
+	err := processFile(in, nil, &buf, stdin)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	expected, err := ioutil.ReadFile(out)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	if got := buf.Bytes(); !bytes.Equal(got, expected) {
+		t.Errorf("(gofmt %s) != %s (see %s.gofmt)", in, out, in)
+		d, err := diff(expected, got)
+		if err == nil {
+			t.Errorf("%s", d)
+		}
+		if err := ioutil.WriteFile(in+".gofmt", got, 0666); err != nil {
+			t.Error(err)
+		}
+	}
+}
+
+var tests = []struct {
+	in, flags string
+}{
+	{"gofmt.go", ""},
+	{"gofmt_test.go", ""},
+	{"testdata/composites.input", "-s"},
+	{"testdata/slices1.input", "-s"},
+	{"testdata/slices2.input", "-s"},
+	{"testdata/old.input", ""},
+	{"testdata/rewrite1.input", "-r=Foo->Bar"},
+	{"testdata/rewrite2.input", "-r=int->bool"},
+	{"testdata/rewrite3.input", "-r=x->x"},
+	{"testdata/rewrite4.input", "-r=(x)->x"},
+	{"testdata/rewrite5.input", "-r=x+x->2*x"},
+	{"testdata/rewrite6.input", "-r=fun(x)->Fun(x)"},
+	{"testdata/rewrite7.input", "-r=fun(x...)->Fun(x)"},
+	{"testdata/rewrite8.input", "-r=interface{}->int"},
+	{"testdata/stdin*.input", "-stdin"},
+	{"testdata/comments.input", ""},
+	{"testdata/import.input", ""},
+	{"testdata/crlf.input", ""},       // test case for issue 3961; see also TestCRLF
+	{"testdata/typeswitch.input", ""}, // test case for issue 4470
+}
+
+func TestRewrite(t *testing.T) {
+	for _, test := range tests {
+		match, err := filepath.Glob(test.in)
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+		for _, in := range match {
+			out := in
+			if strings.HasSuffix(in, ".input") {
+				out = in[:len(in)-len(".input")] + ".golden"
+			}
+			runTest(t, in, out, test.flags)
+			if in != out {
+				// Check idempotence.
+				runTest(t, out, out, test.flags)
+			}
+		}
+	}
+}
+
+func TestCRLF(t *testing.T) {
+	const input = "testdata/crlf.input"   // must contain CR/LF's
+	const golden = "testdata/crlf.golden" // must not contain any CR's
+
+	data, err := ioutil.ReadFile(input)
+	if err != nil {
+		t.Error(err)
+	}
+	if bytes.Index(data, []byte("\r\n")) < 0 {
+		t.Errorf("%s contains no CR/LF's", input)
+	}
+
+	data, err = ioutil.ReadFile(golden)
+	if err != nil {
+		t.Error(err)
+	}
+	if bytes.Index(data, []byte("\r")) >= 0 {
+		t.Errorf("%s contains CR's", golden)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/long_test.go b/third_party/gofrontend/libgo/go/cmd/gofmt/long_test.go
new file mode 100644
index 0000000..108278b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/long_test.go
@@ -0,0 +1,159 @@
+// Copyright 2011 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.
+
+// This test applies gofmt to all Go files under -root.
+// To test specific files provide a list of comma-separated
+// filenames via the -files flag: go test -files=gofmt.go .
+
+package main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/ast"
+	"go/printer"
+	"go/token"
+	"io"
+	"os"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+var (
+	root    = flag.String("root", runtime.GOROOT(), "test root directory")
+	files   = flag.String("files", "", "comma-separated list of files to test")
+	ngo     = flag.Int("n", runtime.NumCPU(), "number of goroutines used")
+	verbose = flag.Bool("verbose", false, "verbose mode")
+	nfiles  int // number of files processed
+)
+
+func gofmt(fset *token.FileSet, filename string, src *bytes.Buffer) error {
+	f, _, err := parse(fset, filename, src.Bytes(), false)
+	if err != nil {
+		return err
+	}
+	ast.SortImports(fset, f)
+	src.Reset()
+	return (&printer.Config{Mode: printerMode, Tabwidth: tabWidth}).Fprint(src, fset, f)
+}
+
+func testFile(t *testing.T, b1, b2 *bytes.Buffer, filename string) {
+	// open file
+	f, err := os.Open(filename)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	// read file
+	b1.Reset()
+	_, err = io.Copy(b1, f)
+	f.Close()
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	// exclude files w/ syntax errors (typically test cases)
+	fset := token.NewFileSet()
+	if _, _, err = parse(fset, filename, b1.Bytes(), false); err != nil {
+		if *verbose {
+			fmt.Fprintf(os.Stderr, "ignoring %s\n", err)
+		}
+		return
+	}
+
+	// gofmt file
+	if err = gofmt(fset, filename, b1); err != nil {
+		t.Errorf("1st gofmt failed: %v", err)
+		return
+	}
+
+	// make a copy of the result
+	b2.Reset()
+	b2.Write(b1.Bytes())
+
+	// gofmt result again
+	if err = gofmt(fset, filename, b2); err != nil {
+		t.Errorf("2nd gofmt failed: %v", err)
+		return
+	}
+
+	// the first and 2nd result should be identical
+	if !bytes.Equal(b1.Bytes(), b2.Bytes()) {
+		t.Errorf("gofmt %s not idempotent", filename)
+	}
+}
+
+func testFiles(t *testing.T, filenames <-chan string, done chan<- int) {
+	b1 := new(bytes.Buffer)
+	b2 := new(bytes.Buffer)
+	for filename := range filenames {
+		testFile(t, b1, b2, filename)
+	}
+	done <- 0
+}
+
+func genFilenames(t *testing.T, filenames chan<- string) {
+	defer close(filenames)
+
+	handleFile := func(filename string, fi os.FileInfo, err error) error {
+		if err != nil {
+			t.Error(err)
+			return nil
+		}
+		if isGoFile(fi) {
+			filenames <- filename
+			nfiles++
+		}
+		return nil
+	}
+
+	// test Go files provided via -files, if any
+	if *files != "" {
+		for _, filename := range strings.Split(*files, ",") {
+			fi, err := os.Stat(filename)
+			handleFile(filename, fi, err)
+		}
+		return // ignore files under -root
+	}
+
+	// otherwise, test all Go files under *root
+	filepath.Walk(*root, handleFile)
+}
+
+func TestAll(t *testing.T) {
+	if testing.Short() {
+		return
+	}
+
+	if *ngo < 1 {
+		*ngo = 1 // make sure test is run
+	}
+	if *verbose {
+		fmt.Printf("running test using %d goroutines\n", *ngo)
+	}
+
+	// generate filenames
+	filenames := make(chan string, 32)
+	go genFilenames(t, filenames)
+
+	// launch test goroutines
+	done := make(chan int)
+	for i := 0; i < *ngo; i++ {
+		go testFiles(t, filenames, done)
+	}
+
+	// wait for all test goroutines to complete
+	for i := 0; i < *ngo; i++ {
+		<-done
+	}
+
+	if *verbose {
+		fmt.Printf("processed %d files\n", nfiles)
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/rewrite.go b/third_party/gofrontend/libgo/go/cmd/gofmt/rewrite.go
new file mode 100644
index 0000000..fb6c6fc
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/rewrite.go
@@ -0,0 +1,306 @@
+// 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 main
+
+import (
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/token"
+	"os"
+	"reflect"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+)
+
+func initRewrite() {
+	if *rewriteRule == "" {
+		rewrite = nil // disable any previous rewrite
+		return
+	}
+	f := strings.Split(*rewriteRule, "->")
+	if len(f) != 2 {
+		fmt.Fprintf(os.Stderr, "rewrite rule must be of the form 'pattern -> replacement'\n")
+		os.Exit(2)
+	}
+	pattern := parseExpr(f[0], "pattern")
+	replace := parseExpr(f[1], "replacement")
+	rewrite = func(p *ast.File) *ast.File { return rewriteFile(pattern, replace, p) }
+}
+
+// parseExpr parses s as an expression.
+// It might make sense to expand this to allow statement patterns,
+// but there are problems with preserving formatting and also
+// with what a wildcard for a statement looks like.
+func parseExpr(s, what string) ast.Expr {
+	x, err := parser.ParseExpr(s)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "parsing %s %s at %s\n", what, s, err)
+		os.Exit(2)
+	}
+	return x
+}
+
+// Keep this function for debugging.
+/*
+func dump(msg string, val reflect.Value) {
+	fmt.Printf("%s:\n", msg)
+	ast.Print(fileSet, val.Interface())
+	fmt.Println()
+}
+*/
+
+// rewriteFile applies the rewrite rule 'pattern -> replace' to an entire file.
+func rewriteFile(pattern, replace ast.Expr, p *ast.File) *ast.File {
+	cmap := ast.NewCommentMap(fileSet, p, p.Comments)
+	m := make(map[string]reflect.Value)
+	pat := reflect.ValueOf(pattern)
+	repl := reflect.ValueOf(replace)
+
+	var rewriteVal func(val reflect.Value) reflect.Value
+	rewriteVal = func(val reflect.Value) reflect.Value {
+		// don't bother if val is invalid to start with
+		if !val.IsValid() {
+			return reflect.Value{}
+		}
+		for k := range m {
+			delete(m, k)
+		}
+		val = apply(rewriteVal, val)
+		if match(m, pat, val) {
+			val = subst(m, repl, reflect.ValueOf(val.Interface().(ast.Node).Pos()))
+		}
+		return val
+	}
+
+	r := apply(rewriteVal, reflect.ValueOf(p)).Interface().(*ast.File)
+	r.Comments = cmap.Filter(r).Comments() // recreate comments list
+	return r
+}
+
+// set is a wrapper for x.Set(y); it protects the caller from panics if x cannot be changed to y.
+func set(x, y reflect.Value) {
+	// don't bother if x cannot be set or y is invalid
+	if !x.CanSet() || !y.IsValid() {
+		return
+	}
+	defer func() {
+		if x := recover(); x != nil {
+			if s, ok := x.(string); ok &&
+				(strings.Contains(s, "type mismatch") || strings.Contains(s, "not assignable")) {
+				// x cannot be set to y - ignore this rewrite
+				return
+			}
+			panic(x)
+		}
+	}()
+	x.Set(y)
+}
+
+// Values/types for special cases.
+var (
+	objectPtrNil = reflect.ValueOf((*ast.Object)(nil))
+	scopePtrNil  = reflect.ValueOf((*ast.Scope)(nil))
+
+	identType     = reflect.TypeOf((*ast.Ident)(nil))
+	objectPtrType = reflect.TypeOf((*ast.Object)(nil))
+	positionType  = reflect.TypeOf(token.NoPos)
+	callExprType  = reflect.TypeOf((*ast.CallExpr)(nil))
+	scopePtrType  = reflect.TypeOf((*ast.Scope)(nil))
+)
+
+// apply replaces each AST field x in val with f(x), returning val.
+// To avoid extra conversions, f operates on the reflect.Value form.
+func apply(f func(reflect.Value) reflect.Value, val reflect.Value) reflect.Value {
+	if !val.IsValid() {
+		return reflect.Value{}
+	}
+
+	// *ast.Objects introduce cycles and are likely incorrect after
+	// rewrite; don't follow them but replace with nil instead
+	if val.Type() == objectPtrType {
+		return objectPtrNil
+	}
+
+	// similarly for scopes: they are likely incorrect after a rewrite;
+	// replace them with nil
+	if val.Type() == scopePtrType {
+		return scopePtrNil
+	}
+
+	switch v := reflect.Indirect(val); v.Kind() {
+	case reflect.Slice:
+		for i := 0; i < v.Len(); i++ {
+			e := v.Index(i)
+			set(e, f(e))
+		}
+	case reflect.Struct:
+		for i := 0; i < v.NumField(); i++ {
+			e := v.Field(i)
+			set(e, f(e))
+		}
+	case reflect.Interface:
+		e := v.Elem()
+		set(v, f(e))
+	}
+	return val
+}
+
+func isWildcard(s string) bool {
+	rune, size := utf8.DecodeRuneInString(s)
+	return size == len(s) && unicode.IsLower(rune)
+}
+
+// match returns true if pattern matches val,
+// recording wildcard submatches in m.
+// If m == nil, match checks whether pattern == val.
+func match(m map[string]reflect.Value, pattern, val reflect.Value) bool {
+	// Wildcard matches any expression.  If it appears multiple
+	// times in the pattern, it must match the same expression
+	// each time.
+	if m != nil && pattern.IsValid() && pattern.Type() == identType {
+		name := pattern.Interface().(*ast.Ident).Name
+		if isWildcard(name) && val.IsValid() {
+			// wildcards only match valid (non-nil) expressions.
+			if _, ok := val.Interface().(ast.Expr); ok && !val.IsNil() {
+				if old, ok := m[name]; ok {
+					return match(nil, old, val)
+				}
+				m[name] = val
+				return true
+			}
+		}
+	}
+
+	// Otherwise, pattern and val must match recursively.
+	if !pattern.IsValid() || !val.IsValid() {
+		return !pattern.IsValid() && !val.IsValid()
+	}
+	if pattern.Type() != val.Type() {
+		return false
+	}
+
+	// Special cases.
+	switch pattern.Type() {
+	case identType:
+		// For identifiers, only the names need to match
+		// (and none of the other *ast.Object information).
+		// This is a common case, handle it all here instead
+		// of recursing down any further via reflection.
+		p := pattern.Interface().(*ast.Ident)
+		v := val.Interface().(*ast.Ident)
+		return p == nil && v == nil || p != nil && v != nil && p.Name == v.Name
+	case objectPtrType, positionType:
+		// object pointers and token positions always match
+		return true
+	case callExprType:
+		// For calls, the Ellipsis fields (token.Position) must
+		// match since that is how f(x) and f(x...) are different.
+		// Check them here but fall through for the remaining fields.
+		p := pattern.Interface().(*ast.CallExpr)
+		v := val.Interface().(*ast.CallExpr)
+		if p.Ellipsis.IsValid() != v.Ellipsis.IsValid() {
+			return false
+		}
+	}
+
+	p := reflect.Indirect(pattern)
+	v := reflect.Indirect(val)
+	if !p.IsValid() || !v.IsValid() {
+		return !p.IsValid() && !v.IsValid()
+	}
+
+	switch p.Kind() {
+	case reflect.Slice:
+		if p.Len() != v.Len() {
+			return false
+		}
+		for i := 0; i < p.Len(); i++ {
+			if !match(m, p.Index(i), v.Index(i)) {
+				return false
+			}
+		}
+		return true
+
+	case reflect.Struct:
+		if p.NumField() != v.NumField() {
+			return false
+		}
+		for i := 0; i < p.NumField(); i++ {
+			if !match(m, p.Field(i), v.Field(i)) {
+				return false
+			}
+		}
+		return true
+
+	case reflect.Interface:
+		return match(m, p.Elem(), v.Elem())
+	}
+
+	// Handle token integers, etc.
+	return p.Interface() == v.Interface()
+}
+
+// subst returns a copy of pattern with values from m substituted in place
+// of wildcards and pos used as the position of tokens from the pattern.
+// if m == nil, subst returns a copy of pattern and doesn't change the line
+// number information.
+func subst(m map[string]reflect.Value, pattern reflect.Value, pos reflect.Value) reflect.Value {
+	if !pattern.IsValid() {
+		return reflect.Value{}
+	}
+
+	// Wildcard gets replaced with map value.
+	if m != nil && pattern.Type() == identType {
+		name := pattern.Interface().(*ast.Ident).Name
+		if isWildcard(name) {
+			if old, ok := m[name]; ok {
+				return subst(nil, old, reflect.Value{})
+			}
+		}
+	}
+
+	if pos.IsValid() && pattern.Type() == positionType {
+		// use new position only if old position was valid in the first place
+		if old := pattern.Interface().(token.Pos); !old.IsValid() {
+			return pattern
+		}
+		return pos
+	}
+
+	// Otherwise copy.
+	switch p := pattern; p.Kind() {
+	case reflect.Slice:
+		v := reflect.MakeSlice(p.Type(), p.Len(), p.Len())
+		for i := 0; i < p.Len(); i++ {
+			v.Index(i).Set(subst(m, p.Index(i), pos))
+		}
+		return v
+
+	case reflect.Struct:
+		v := reflect.New(p.Type()).Elem()
+		for i := 0; i < p.NumField(); i++ {
+			v.Field(i).Set(subst(m, p.Field(i), pos))
+		}
+		return v
+
+	case reflect.Ptr:
+		v := reflect.New(p.Type()).Elem()
+		if elem := p.Elem(); elem.IsValid() {
+			v.Set(subst(m, elem, pos).Addr())
+		}
+		return v
+
+	case reflect.Interface:
+		v := reflect.New(p.Type()).Elem()
+		if elem := p.Elem(); elem.IsValid() {
+			v.Set(subst(m, elem, pos))
+		}
+		return v
+	}
+
+	return pattern
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/simplify.go b/third_party/gofrontend/libgo/go/cmd/gofmt/simplify.go
new file mode 100644
index 0000000..45d000d
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/simplify.go
@@ -0,0 +1,121 @@
+// Copyright 2010 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 (
+	"go/ast"
+	"go/token"
+	"reflect"
+)
+
+type simplifier struct {
+	hasDotImport bool // package file contains: import . "some/import/path"
+}
+
+func (s *simplifier) Visit(node ast.Node) ast.Visitor {
+	switch n := node.(type) {
+	case *ast.CompositeLit:
+		// array, slice, and map composite literals may be simplified
+		outer := n
+		var eltType ast.Expr
+		switch typ := outer.Type.(type) {
+		case *ast.ArrayType:
+			eltType = typ.Elt
+		case *ast.MapType:
+			eltType = typ.Value
+		}
+
+		if eltType != nil {
+			typ := reflect.ValueOf(eltType)
+			for i, x := range outer.Elts {
+				px := &outer.Elts[i]
+				// look at value of indexed/named elements
+				if t, ok := x.(*ast.KeyValueExpr); ok {
+					x = t.Value
+					px = &t.Value
+				}
+				ast.Walk(s, x) // simplify x
+				// if the element is a composite literal and its literal type
+				// matches the outer literal's element type exactly, the inner
+				// literal type may be omitted
+				if inner, ok := x.(*ast.CompositeLit); ok {
+					if match(nil, typ, reflect.ValueOf(inner.Type)) {
+						inner.Type = nil
+					}
+				}
+				// if the outer literal's element type is a pointer type *T
+				// and the element is & of a composite literal of type T,
+				// the inner &T may be omitted.
+				if ptr, ok := eltType.(*ast.StarExpr); ok {
+					if addr, ok := x.(*ast.UnaryExpr); ok && addr.Op == token.AND {
+						if inner, ok := addr.X.(*ast.CompositeLit); ok {
+							if match(nil, reflect.ValueOf(ptr.X), reflect.ValueOf(inner.Type)) {
+								inner.Type = nil // drop T
+								*px = inner      // drop &
+							}
+						}
+					}
+				}
+			}
+
+			// node was simplified - stop walk (there are no subnodes to simplify)
+			return nil
+		}
+
+	case *ast.SliceExpr:
+		// a slice expression of the form: s[a:len(s)]
+		// can be simplified to: s[a:]
+		// if s is "simple enough" (for now we only accept identifiers)
+		if s.hasDotImport {
+			// if dot imports are present, we cannot be certain that an
+			// unresolved "len" identifier refers to the predefined len()
+			break
+		}
+		if s, _ := n.X.(*ast.Ident); s != nil && s.Obj != nil {
+			// the array/slice object is a single, resolved identifier
+			if call, _ := n.High.(*ast.CallExpr); call != nil && len(call.Args) == 1 && !call.Ellipsis.IsValid() {
+				// the high expression is a function call with a single argument
+				if fun, _ := call.Fun.(*ast.Ident); fun != nil && fun.Name == "len" && fun.Obj == nil {
+					// the function called is "len" and it is not locally defined; and
+					// because we don't have dot imports, it must be the predefined len()
+					if arg, _ := call.Args[0].(*ast.Ident); arg != nil && arg.Obj == s.Obj {
+						// the len argument is the array/slice object
+						n.High = nil
+					}
+				}
+			}
+		}
+		// Note: We could also simplify slice expressions of the form s[0:b] to s[:b]
+		//       but we leave them as is since sometimes we want to be very explicit
+		//       about the lower bound.
+		// An example where the 0 helps:
+		//       x, y, z := b[0:2], b[2:4], b[4:6]
+		// An example where it does not:
+		//       x, y := b[:n], b[n:]
+
+	case *ast.RangeStmt:
+		// a range of the form: for x, _ = range v {...}
+		// can be simplified to: for x = range v {...}
+		if ident, _ := n.Value.(*ast.Ident); ident != nil && ident.Name == "_" {
+			n.Value = nil
+		}
+	}
+
+	return s
+}
+
+func simplify(f *ast.File) {
+	var s simplifier
+
+	// determine if f contains dot imports
+	for _, imp := range f.Imports {
+		if imp.Name != nil && imp.Name.Name == "." {
+			s.hasDotImport = true
+			break
+		}
+	}
+
+	ast.Walk(&s, f)
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/comments.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/comments.golden
new file mode 100644
index 0000000..ad6bcaf
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/comments.golden
@@ -0,0 +1,9 @@
+package main
+
+func main() {}
+
+// comment here
+
+func f() {}
+
+//line foo.go:1
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/comments.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/comments.input
new file mode 100644
index 0000000..ad6bcaf
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/comments.input
@@ -0,0 +1,9 @@
+package main
+
+func main() {}
+
+// comment here
+
+func f() {}
+
+//line foo.go:1
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/composites.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/composites.golden
new file mode 100644
index 0000000..b2825e7
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/composites.golden
@@ -0,0 +1,202 @@
+package P
+
+type T struct {
+	x, y int
+}
+
+var _ = [42]T{
+	{},
+	{1, 2},
+	{3, 4},
+}
+
+var _ = [...]T{
+	{},
+	{1, 2},
+	{3, 4},
+}
+
+var _ = []T{
+	{},
+	{1, 2},
+	{3, 4},
+}
+
+var _ = []T{
+	{},
+	10: {1, 2},
+	20: {3, 4},
+}
+
+var _ = []struct {
+	x, y int
+}{
+	{},
+	10: {1, 2},
+	20: {3, 4},
+}
+
+var _ = []interface{}{
+	T{},
+	10: T{1, 2},
+	20: T{3, 4},
+}
+
+var _ = [][]int{
+	{},
+	{1, 2},
+	{3, 4},
+}
+
+var _ = [][]int{
+	([]int{}),
+	([]int{1, 2}),
+	{3, 4},
+}
+
+var _ = [][][]int{
+	{},
+	{
+		{},
+		{0, 1, 2, 3},
+		{4, 5},
+	},
+}
+
+var _ = map[string]T{
+	"foo": {},
+	"bar": {1, 2},
+	"bal": {3, 4},
+}
+
+var _ = map[string]struct {
+	x, y int
+}{
+	"foo": {},
+	"bar": {1, 2},
+	"bal": {3, 4},
+}
+
+var _ = map[string]interface{}{
+	"foo": T{},
+	"bar": T{1, 2},
+	"bal": T{3, 4},
+}
+
+var _ = map[string][]int{
+	"foo": {},
+	"bar": {1, 2},
+	"bal": {3, 4},
+}
+
+var _ = map[string][]int{
+	"foo": ([]int{}),
+	"bar": ([]int{1, 2}),
+	"bal": {3, 4},
+}
+
+// from exp/4s/data.go
+var pieces4 = []Piece{
+	{0, 0, Point{4, 1}, []Point{{0, 0}, {1, 0}, {1, 0}, {1, 0}}, nil, nil},
+	{1, 0, Point{1, 4}, []Point{{0, 0}, {0, 1}, {0, 1}, {0, 1}}, nil, nil},
+	{2, 0, Point{4, 1}, []Point{{0, 0}, {1, 0}, {1, 0}, {1, 0}}, nil, nil},
+	{3, 0, Point{1, 4}, []Point{{0, 0}, {0, 1}, {0, 1}, {0, 1}}, nil, nil},
+}
+
+var _ = [42]*T{
+	{},
+	{1, 2},
+	{3, 4},
+}
+
+var _ = [...]*T{
+	{},
+	{1, 2},
+	{3, 4},
+}
+
+var _ = []*T{
+	{},
+	{1, 2},
+	{3, 4},
+}
+
+var _ = []*T{
+	{},
+	10: {1, 2},
+	20: {3, 4},
+}
+
+var _ = []*struct {
+	x, y int
+}{
+	{},
+	10: {1, 2},
+	20: {3, 4},
+}
+
+var _ = []interface{}{
+	&T{},
+	10: &T{1, 2},
+	20: &T{3, 4},
+}
+
+var _ = []*[]int{
+	{},
+	{1, 2},
+	{3, 4},
+}
+
+var _ = []*[]int{
+	(&[]int{}),
+	(&[]int{1, 2}),
+	{3, 4},
+}
+
+var _ = []*[]*[]int{
+	{},
+	{
+		{},
+		{0, 1, 2, 3},
+		{4, 5},
+	},
+}
+
+var _ = map[string]*T{
+	"foo": {},
+	"bar": {1, 2},
+	"bal": {3, 4},
+}
+
+var _ = map[string]*struct {
+	x, y int
+}{
+	"foo": {},
+	"bar": {1, 2},
+	"bal": {3, 4},
+}
+
+var _ = map[string]interface{}{
+	"foo": &T{},
+	"bar": &T{1, 2},
+	"bal": &T{3, 4},
+}
+
+var _ = map[string]*[]int{
+	"foo": {},
+	"bar": {1, 2},
+	"bal": {3, 4},
+}
+
+var _ = map[string]*[]int{
+	"foo": (&[]int{}),
+	"bar": (&[]int{1, 2}),
+	"bal": {3, 4},
+}
+
+var pieces4 = []*Piece{
+	{0, 0, Point{4, 1}, []Point{{0, 0}, {1, 0}, {1, 0}, {1, 0}}, nil, nil},
+	{1, 0, Point{1, 4}, []Point{{0, 0}, {0, 1}, {0, 1}, {0, 1}}, nil, nil},
+	{2, 0, Point{4, 1}, []Point{{0, 0}, {1, 0}, {1, 0}, {1, 0}}, nil, nil},
+	{3, 0, Point{1, 4}, []Point{{0, 0}, {0, 1}, {0, 1}, {0, 1}}, nil, nil},
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/composites.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/composites.input
new file mode 100644
index 0000000..7210daf
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/composites.input
@@ -0,0 +1,202 @@
+package P
+
+type T struct {
+	x, y int
+}
+
+var _ = [42]T{
+	T{},
+	T{1, 2},
+	T{3, 4},
+}
+
+var _ = [...]T{
+	T{},
+	T{1, 2},
+	T{3, 4},
+}
+
+var _ = []T{
+	T{},
+	T{1, 2},
+	T{3, 4},
+}
+
+var _ = []T{
+	T{},
+	10: T{1, 2},
+	20: T{3, 4},
+}
+
+var _ = []struct {
+	x, y int
+}{
+	struct{ x, y int }{},
+	10: struct{ x, y int }{1, 2},
+	20: struct{ x, y int }{3, 4},
+}
+
+var _ = []interface{}{
+	T{},
+	10: T{1, 2},
+	20: T{3, 4},
+}
+
+var _ = [][]int{
+	[]int{},
+	[]int{1, 2},
+	[]int{3, 4},
+}
+
+var _ = [][]int{
+	([]int{}),
+	([]int{1, 2}),
+	[]int{3, 4},
+}
+
+var _ = [][][]int{
+	[][]int{},
+	[][]int{
+		[]int{},
+		[]int{0, 1, 2, 3},
+		[]int{4, 5},
+	},
+}
+
+var _ = map[string]T{
+	"foo": T{},
+	"bar": T{1, 2},
+	"bal": T{3, 4},
+}
+
+var _ = map[string]struct {
+	x, y int
+}{
+	"foo": struct{ x, y int }{},
+	"bar": struct{ x, y int }{1, 2},
+	"bal": struct{ x, y int }{3, 4},
+}
+
+var _ = map[string]interface{}{
+	"foo": T{},
+	"bar": T{1, 2},
+	"bal": T{3, 4},
+}
+
+var _ = map[string][]int{
+	"foo": []int{},
+	"bar": []int{1, 2},
+	"bal": []int{3, 4},
+}
+
+var _ = map[string][]int{
+	"foo": ([]int{}),
+	"bar": ([]int{1, 2}),
+	"bal": []int{3, 4},
+}
+
+// from exp/4s/data.go
+var pieces4 = []Piece{
+	Piece{0, 0, Point{4, 1}, []Point{Point{0, 0}, Point{1, 0}, Point{1, 0}, Point{1, 0}}, nil, nil},
+	Piece{1, 0, Point{1, 4}, []Point{Point{0, 0}, Point{0, 1}, Point{0, 1}, Point{0, 1}}, nil, nil},
+	Piece{2, 0, Point{4, 1}, []Point{Point{0, 0}, Point{1, 0}, Point{1, 0}, Point{1, 0}}, nil, nil},
+	Piece{3, 0, Point{1, 4}, []Point{Point{0, 0}, Point{0, 1}, Point{0, 1}, Point{0, 1}}, nil, nil},
+}
+
+var _ = [42]*T{
+	&T{},
+	&T{1, 2},
+	&T{3, 4},
+}
+
+var _ = [...]*T{
+	&T{},
+	&T{1, 2},
+	&T{3, 4},
+}
+
+var _ = []*T{
+	&T{},
+	&T{1, 2},
+	&T{3, 4},
+}
+
+var _ = []*T{
+	&T{},
+	10: &T{1, 2},
+	20: &T{3, 4},
+}
+
+var _ = []*struct {
+	x, y int
+}{
+	&struct{ x, y int }{},
+	10: &struct{ x, y int }{1, 2},
+	20: &struct{ x, y int }{3, 4},
+}
+
+var _ = []interface{}{
+	&T{},
+	10: &T{1, 2},
+	20: &T{3, 4},
+}
+
+var _ = []*[]int{
+	&[]int{},
+	&[]int{1, 2},
+	&[]int{3, 4},
+}
+
+var _ = []*[]int{
+	(&[]int{}),
+	(&[]int{1, 2}),
+	&[]int{3, 4},
+}
+
+var _ = []*[]*[]int{
+	&[]*[]int{},
+	&[]*[]int{
+		&[]int{},
+		&[]int{0, 1, 2, 3},
+		&[]int{4, 5},
+	},
+}
+
+var _ = map[string]*T{
+	"foo": &T{},
+	"bar": &T{1, 2},
+	"bal": &T{3, 4},
+}
+
+var _ = map[string]*struct {
+	x, y int
+}{
+	"foo": &struct{ x, y int }{},
+	"bar": &struct{ x, y int }{1, 2},
+	"bal": &struct{ x, y int }{3, 4},
+}
+
+var _ = map[string]interface{}{
+	"foo": &T{},
+	"bar": &T{1, 2},
+	"bal": &T{3, 4},
+}
+
+var _ = map[string]*[]int{
+	"foo": &[]int{},
+	"bar": &[]int{1, 2},
+	"bal": &[]int{3, 4},
+}
+
+var _ = map[string]*[]int{
+	"foo": (&[]int{}),
+	"bar": (&[]int{1, 2}),
+	"bal": &[]int{3, 4},
+}
+
+var pieces4 = []*Piece{
+	&Piece{0, 0, Point{4, 1}, []Point{Point{0, 0}, Point{1, 0}, Point{1, 0}, Point{1, 0}}, nil, nil},
+	&Piece{1, 0, Point{1, 4}, []Point{Point{0, 0}, Point{0, 1}, Point{0, 1}, Point{0, 1}}, nil, nil},
+	&Piece{2, 0, Point{4, 1}, []Point{Point{0, 0}, Point{1, 0}, Point{1, 0}, Point{1, 0}}, nil, nil},
+	&Piece{3, 0, Point{1, 4}, []Point{Point{0, 0}, Point{0, 1}, Point{0, 1}, Point{0, 1}}, nil, nil},
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/crlf.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/crlf.golden
new file mode 100644
index 0000000..57679f7
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/crlf.golden
@@ -0,0 +1,12 @@
+/*
+	Source containing CR/LF line endings.
+	The gofmt'ed output must only have LF
+	line endings.
+*/
+package main
+
+func main() {
+	// line comment
+	println("hello, world!") // another line comment
+	println()
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/crlf.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/crlf.input
new file mode 100644
index 0000000..61a1aa0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/crlf.input
@@ -0,0 +1,12 @@
+/*

+	Source containing CR/LF line endings.

+	The gofmt'ed output must only have LF

+	line endings.

+*/

+package main

+

+func main() {

+	// line comment

+	println("hello, world!") // another line comment

+	println()

+}

diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/import.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/import.golden
new file mode 100644
index 0000000..51d7be7
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/import.golden
@@ -0,0 +1,126 @@
+package main
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"log"
+	"math"
+)
+
+import (
+	"fmt"
+
+	"math"
+
+	"log"
+
+	"errors"
+
+	"io"
+)
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"log"
+	"math"
+
+	"fmt"
+
+	"math"
+
+	"log"
+
+	"errors"
+
+	"io"
+)
+
+import (
+	// a block with comments
+	"errors"
+	"fmt" // for Printf
+	"io"  // for Reader
+	"log" // for Fatal
+	"math"
+)
+
+import (
+	"fmt" // for Printf
+
+	"math"
+
+	"log" // for Fatal
+
+	"errors"
+
+	"io" // for Reader
+)
+
+import (
+	// for Printf
+	"fmt"
+
+	"math"
+
+	// for Fatal
+	"log"
+
+	"errors"
+
+	// for Reader
+	"io"
+)
+
+import (
+	"errors"
+	"fmt" // for Printf
+	"io"  // for Reader
+	"log" // for Fatal
+	"math"
+
+	"fmt" // for Printf
+
+	"math"
+
+	"log" // for Fatal
+
+	"errors"
+
+	"io" // for Reader
+)
+
+import (
+	"fmt" // for Printf
+
+	"errors"
+	"io"  // for Reader
+	"log" // for Fatal
+	"math"
+
+	"errors"
+	"fmt" // for Printf
+	"io"  // for Reader
+	"log" // for Fatal
+	"math"
+)
+
+// Test deduping and extended sorting
+import (
+	a "A" // aA
+	b "A" // bA1
+	b "A" // bA2
+	"B"   // B
+	. "B" // .B
+	_ "B" // _b
+	"C"
+	a "D" // aD
+)
+
+import (
+	"dedup_by_group"
+
+	"dedup_by_group"
+)
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/import.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/import.input
new file mode 100644
index 0000000..9a4b09d
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/import.input
@@ -0,0 +1,131 @@
+package main
+
+import (
+	"fmt"
+	"math"
+	"log"
+	"errors"
+	"io"
+)
+
+import (
+	"fmt"
+
+	"math"
+
+	"log"
+
+	"errors"
+
+	"io"
+)
+
+import (
+	"fmt"
+	"math"
+	"log"
+	"errors"
+	"io"
+
+	"fmt"
+
+	"math"
+
+	"log"
+
+	"errors"
+
+	"io"
+)
+
+import (
+	// a block with comments
+	"fmt" // for Printf
+	"math"
+	"log" // for Fatal
+	"errors"
+	"io" // for Reader
+)
+
+import (
+	"fmt" // for Printf
+
+	"math"
+
+	"log" // for Fatal
+
+	"errors"
+
+	"io" // for Reader
+)
+
+import (
+	// for Printf
+	"fmt"
+
+	"math"
+
+	// for Fatal
+	"log"
+
+	"errors"
+
+	// for Reader
+	"io"
+)
+
+import (
+	"fmt" // for Printf
+	"math"
+	"log" // for Fatal
+	"errors"
+	"io" // for Reader
+
+	"fmt" // for Printf
+
+	"math"
+
+	"log" // for Fatal
+
+	"errors"
+
+	"io" // for Reader
+)
+
+import (
+	"fmt" // for Printf
+
+	"math"
+	"log" // for Fatal
+	"errors"
+	"io" // for Reader
+
+	"fmt" // for Printf
+	"math"
+	"log" // for Fatal
+	"errors"
+	"io" // for Reader
+)
+
+// Test deduping and extended sorting
+import (
+	"B" // B
+	a "A" // aA
+	b "A" // bA2
+	b "A" // bA1
+	. "B" // .B
+	. "B"
+	"C"
+	"C"
+	"C"
+	a "D" // aD
+	"B"
+	_ "B" // _b
+)
+
+import (
+	"dedup_by_group"
+	"dedup_by_group"
+
+	"dedup_by_group"
+)
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/old.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/old.golden
new file mode 100644
index 0000000..95a0b72
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/old.golden
@@ -0,0 +1,9 @@
+package P
+
+func f() {
+	if x {
+		y
+	} else {
+		z
+	}
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/old.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/old.input
new file mode 100644
index 0000000..e24eed2
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/old.input
@@ -0,0 +1,8 @@
+package P
+
+func f() {
+	if x {
+		y
+	} else
+		z
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite1.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite1.golden
new file mode 100644
index 0000000..d9beb37
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite1.golden
@@ -0,0 +1,12 @@
+// Copyright 2011 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
+
+type Bar int
+
+func main() {
+	var a Bar
+	println(a)
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite1.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite1.input
new file mode 100644
index 0000000..bdb8943
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite1.input
@@ -0,0 +1,12 @@
+// Copyright 2011 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
+
+type Foo int
+
+func main() {
+	var a Foo
+	println(a)
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite2.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite2.golden
new file mode 100644
index 0000000..64c67ff
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite2.golden
@@ -0,0 +1,10 @@
+// Copyright 2011 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 p
+
+// Slices have nil Len values in the corresponding ast.ArrayType
+// node and reflect.NewValue(slice.Len) is an invalid reflect.Value.
+// The rewriter must not crash in that case. Was issue 1696.
+func f() []bool {}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite2.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite2.input
new file mode 100644
index 0000000..2117144
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite2.input
@@ -0,0 +1,10 @@
+// Copyright 2011 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 p
+
+// Slices have nil Len values in the corresponding ast.ArrayType
+// node and reflect.NewValue(slice.Len) is an invalid reflect.Value.
+// The rewriter must not crash in that case. Was issue 1696.
+func f() []int {}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite3.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite3.golden
new file mode 100644
index 0000000..0d16d16
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite3.golden
@@ -0,0 +1,12 @@
+// Copyright 2011 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
+
+// Field tags are *ast.BasicLit nodes that are nil when the tag is
+// absent. These nil nodes must not be mistaken for expressions,
+// the rewriter should not try to dereference them. Was issue 2410.
+type Foo struct {
+	Field int
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite3.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite3.input
new file mode 100644
index 0000000..0d16d16
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite3.input
@@ -0,0 +1,12 @@
+// Copyright 2011 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
+
+// Field tags are *ast.BasicLit nodes that are nil when the tag is
+// absent. These nil nodes must not be mistaken for expressions,
+// the rewriter should not try to dereference them. Was issue 2410.
+type Foo struct {
+	Field int
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite4.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite4.golden
new file mode 100644
index 0000000..8dfc81a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite4.golden
@@ -0,0 +1,74 @@
+// 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.
+
+// Rewriting of parenthesized expressions (x) -> x
+// must not drop parentheses if that would lead to
+// wrong association of the operands.
+// Was issue 1847.
+
+package main
+
+// From example 1 of issue 1847.
+func _() {
+	var t = (&T{1000}).Id()
+}
+
+// From example 2 of issue 1847.
+func _() {
+	fmt.Println((*xpp).a)
+}
+
+// Some more test cases.
+func _() {
+	_ = (-x).f
+	_ = (*x).f
+	_ = (&x).f
+	_ = (!x).f
+	_ = -x.f
+	_ = *x.f
+	_ = &x.f
+	_ = !x.f
+	(-x).f()
+	(*x).f()
+	(&x).f()
+	(!x).f()
+	_ = -x.f()
+	_ = *x.f()
+	_ = &x.f()
+	_ = !x.f()
+
+	_ = (-x).f
+	_ = (*x).f
+	_ = (&x).f
+	_ = (!x).f
+	_ = -x.f
+	_ = *x.f
+	_ = &x.f
+	_ = !x.f
+	(-x).f()
+	(*x).f()
+	(&x).f()
+	(!x).f()
+	_ = -x.f()
+	_ = *x.f()
+	_ = &x.f()
+	_ = !x.f()
+
+	_ = -x.f
+	_ = *x.f
+	_ = &x.f
+	_ = !x.f
+	_ = -x.f
+	_ = *x.f
+	_ = &x.f
+	_ = !x.f
+	_ = -x.f()
+	_ = *x.f()
+	_ = &x.f()
+	_ = !x.f()
+	_ = -x.f()
+	_ = *x.f()
+	_ = &x.f()
+	_ = !x.f()
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite4.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite4.input
new file mode 100644
index 0000000..164cc04
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite4.input
@@ -0,0 +1,74 @@
+// 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.
+
+// Rewriting of parenthesized expressions (x) -> x
+// must not drop parentheses if that would lead to
+// wrong association of the operands.
+// Was issue 1847.
+
+package main
+
+// From example 1 of issue 1847.
+func _() {
+	var t = (&T{1000}).Id()
+}
+
+// From example 2 of issue 1847.
+func _() {
+       fmt.Println((*xpp).a)
+}
+
+// Some more test cases.
+func _() {
+	_ = (-x).f
+	_ = (*x).f
+	_ = (&x).f
+	_ = (!x).f
+	_ = (-x.f)
+	_ = (*x.f)
+	_ = (&x.f)
+	_ = (!x.f)
+	(-x).f()
+	(*x).f()
+	(&x).f()
+	(!x).f()
+	_ = (-x.f())
+	_ = (*x.f())
+	_ = (&x.f())
+	_ = (!x.f())
+
+	_ = ((-x)).f
+	_ = ((*x)).f
+	_ = ((&x)).f
+	_ = ((!x)).f
+	_ = ((-x.f))
+	_ = ((*x.f))
+	_ = ((&x.f))
+	_ = ((!x.f))
+	((-x)).f()
+	((*x)).f()
+	((&x)).f()
+	((!x)).f()
+	_ = ((-x.f()))
+	_ = ((*x.f()))
+	_ = ((&x.f()))
+	_ = ((!x.f()))
+
+	_ = -(x).f
+	_ = *(x).f
+	_ = &(x).f
+	_ = !(x).f
+	_ = -x.f
+	_ = *x.f
+	_ = &x.f
+	_ = !x.f
+	_ = -(x).f()
+	_ = *(x).f()
+	_ = &(x).f()
+	_ = !(x).f()
+	_ = -x.f()
+	_ = *x.f()
+	_ = &x.f()
+	_ = !x.f()
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite5.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite5.golden
new file mode 100644
index 0000000..5a448a6
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite5.golden
@@ -0,0 +1,15 @@
+// Copyright 2011 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.
+
+// Rewriting of expressions containing nodes with associated comments to
+// expressions without those nodes must also eliminate the associated
+// comments.
+
+package p
+
+func f(x int) int {
+	_ = 2 * x // this comment remains in the rewrite
+	_ = 2 * x
+	return 2 * x
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite5.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite5.input
new file mode 100644
index 0000000..0d759e6
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite5.input
@@ -0,0 +1,15 @@
+// Copyright 2011 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.
+
+// Rewriting of expressions containing nodes with associated comments to
+// expressions without those nodes must also eliminate the associated
+// comments.
+
+package p
+
+func f(x int) int {
+	_ = x + x // this comment remains in the rewrite
+	_ = x /* this comment must not be in the rewrite */ + x
+	return x /* this comment must not be in the rewrite */ + x
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite6.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite6.golden
new file mode 100644
index 0000000..e565dbd
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite6.golden
@@ -0,0 +1,15 @@
+// Copyright 2013 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.
+
+// Rewriting of calls must take the ... (ellipsis)
+// attribute for the last argument into account.
+
+package p
+
+func fun(x []int) {}
+
+func g(x []int) {
+	Fun(x)    // -r='fun(x)->Fun(x)' should rewrite this to Fun(x)
+	fun(x...) // -r='fun(x)->Fun(x)' should not rewrite this
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite6.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite6.input
new file mode 100644
index 0000000..8c088b3
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite6.input
@@ -0,0 +1,15 @@
+// Copyright 2013 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.
+
+// Rewriting of calls must take the ... (ellipsis)
+// attribute for the last argument into account.
+
+package p
+
+func fun(x []int) {}
+
+func g(x []int) {
+	fun(x)    // -r='fun(x)->Fun(x)' should rewrite this to Fun(x)
+	fun(x...) // -r='fun(x)->Fun(x)' should not rewrite this
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite7.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite7.golden
new file mode 100644
index 0000000..29babad
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite7.golden
@@ -0,0 +1,15 @@
+// Copyright 2013 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.
+
+// Rewriting of calls must take the ... (ellipsis)
+// attribute for the last argument into account.
+
+package p
+
+func fun(x []int) {}
+
+func g(x []int) {
+	fun(x) // -r='fun(x...)->Fun(x)' should not rewrite this
+	Fun(x) // -r='fun(x...)->Fun(x)' should rewrite this to Fun(x)
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite7.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite7.input
new file mode 100644
index 0000000..073e2a3
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite7.input
@@ -0,0 +1,15 @@
+// Copyright 2013 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.
+
+// Rewriting of calls must take the ... (ellipsis)
+// attribute for the last argument into account.
+
+package p
+
+func fun(x []int) {}
+
+func g(x []int) {
+	fun(x)    // -r='fun(x...)->Fun(x)' should not rewrite this
+	fun(x...) // -r='fun(x...)->Fun(x)' should rewrite this to Fun(x)
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite8.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite8.golden
new file mode 100644
index 0000000..cfc452b
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite8.golden
@@ -0,0 +1,10 @@
+// Copyright 2013 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.
+
+// Check that literal type expression rewrites are accepted.
+// Was issue 4406.
+
+package p
+
+type T int
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite8.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite8.input
new file mode 100644
index 0000000..235efa9
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/rewrite8.input
@@ -0,0 +1,10 @@
+// Copyright 2013 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.
+
+// Check that literal type expression rewrites are accepted.
+// Was issue 4406.
+
+package p
+
+type T interface{}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/slices1.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/slices1.golden
new file mode 100644
index 0000000..61e074f
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/slices1.golden
@@ -0,0 +1,58 @@
+// Test cases for slice expression simplification.
+package p
+
+var (
+	a [10]byte
+	b [20]float32
+	s []int
+	t struct {
+		s []byte
+	}
+
+	_ = a[0:]
+	_ = a[1:10]
+	_ = a[2:]
+	_ = a[3:(len(a))]
+	_ = a[len(a) : len(a)-1]
+	_ = a[0:len(b)]
+
+	_ = a[:]
+	_ = a[:10]
+	_ = a[:]
+	_ = a[:(len(a))]
+	_ = a[:len(a)-1]
+	_ = a[:len(b)]
+
+	_ = s[0:]
+	_ = s[1:10]
+	_ = s[2:]
+	_ = s[3:(len(s))]
+	_ = s[len(a) : len(s)-1]
+	_ = s[0:len(b)]
+
+	_ = s[:]
+	_ = s[:10]
+	_ = s[:]
+	_ = s[:(len(s))]
+	_ = s[:len(s)-1]
+	_ = s[:len(b)]
+
+	_ = t.s[0:]
+	_ = t.s[1:10]
+	_ = t.s[2:len(t.s)]
+	_ = t.s[3:(len(t.s))]
+	_ = t.s[len(a) : len(t.s)-1]
+	_ = t.s[0:len(b)]
+
+	_ = t.s[:]
+	_ = t.s[:10]
+	_ = t.s[:len(t.s)]
+	_ = t.s[:(len(t.s))]
+	_ = t.s[:len(t.s)-1]
+	_ = t.s[:len(b)]
+)
+
+func _() {
+	s := s[0:]
+	_ = s
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/slices1.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/slices1.input
new file mode 100644
index 0000000..4d2cbff
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/slices1.input
@@ -0,0 +1,58 @@
+// Test cases for slice expression simplification.
+package p
+
+var (
+	a [10]byte
+	b [20]float32
+	s []int
+	t struct {
+		s []byte
+	}
+
+	_ = a[0:]
+	_ = a[1:10]
+	_ = a[2:len(a)]
+	_ = a[3:(len(a))]
+	_ = a[len(a) : len(a)-1]
+	_ = a[0:len(b)]
+
+	_ = a[:]
+	_ = a[:10]
+	_ = a[:len(a)]
+	_ = a[:(len(a))]
+	_ = a[:len(a)-1]
+	_ = a[:len(b)]
+
+	_ = s[0:]
+	_ = s[1:10]
+	_ = s[2:len(s)]
+	_ = s[3:(len(s))]
+	_ = s[len(a) : len(s)-1]
+	_ = s[0:len(b)]
+
+	_ = s[:]
+	_ = s[:10]
+	_ = s[:len(s)]
+	_ = s[:(len(s))]
+	_ = s[:len(s)-1]
+	_ = s[:len(b)]
+
+	_ = t.s[0:]
+	_ = t.s[1:10]
+	_ = t.s[2:len(t.s)]
+	_ = t.s[3:(len(t.s))]
+	_ = t.s[len(a) : len(t.s)-1]
+	_ = t.s[0:len(b)]
+
+	_ = t.s[:]
+	_ = t.s[:10]
+	_ = t.s[:len(t.s)]
+	_ = t.s[:(len(t.s))]
+	_ = t.s[:len(t.s)-1]
+	_ = t.s[:len(b)]
+)
+
+func _() {
+	s := s[0:len(s)]
+	_ = s
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/slices2.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/slices2.golden
new file mode 100644
index 0000000..433788e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/slices2.golden
@@ -0,0 +1,61 @@
+// Test cases for slice expression simplification.
+// Because of a dot import, these slices must remain untouched.
+package p
+
+import . "math"
+
+var (
+	a [10]byte
+	b [20]float32
+	s []int
+	t struct {
+		s []byte
+	}
+
+	_ = a[0:]
+	_ = a[1:10]
+	_ = a[2:len(a)]
+	_ = a[3:(len(a))]
+	_ = a[len(a) : len(a)-1]
+	_ = a[0:len(b)]
+
+	_ = a[:]
+	_ = a[:10]
+	_ = a[:len(a)]
+	_ = a[:(len(a))]
+	_ = a[:len(a)-1]
+	_ = a[:len(b)]
+
+	_ = s[0:]
+	_ = s[1:10]
+	_ = s[2:len(s)]
+	_ = s[3:(len(s))]
+	_ = s[len(a) : len(s)-1]
+	_ = s[0:len(b)]
+
+	_ = s[:]
+	_ = s[:10]
+	_ = s[:len(s)]
+	_ = s[:(len(s))]
+	_ = s[:len(s)-1]
+	_ = s[:len(b)]
+
+	_ = t.s[0:]
+	_ = t.s[1:10]
+	_ = t.s[2:len(t.s)]
+	_ = t.s[3:(len(t.s))]
+	_ = t.s[len(a) : len(t.s)-1]
+	_ = t.s[0:len(b)]
+
+	_ = t.s[:]
+	_ = t.s[:10]
+	_ = t.s[:len(t.s)]
+	_ = t.s[:(len(t.s))]
+	_ = t.s[:len(t.s)-1]
+	_ = t.s[:len(b)]
+)
+
+func _() {
+	s := s[0:len(s)]
+	_ = s
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/slices2.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/slices2.input
new file mode 100644
index 0000000..433788e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/slices2.input
@@ -0,0 +1,61 @@
+// Test cases for slice expression simplification.
+// Because of a dot import, these slices must remain untouched.
+package p
+
+import . "math"
+
+var (
+	a [10]byte
+	b [20]float32
+	s []int
+	t struct {
+		s []byte
+	}
+
+	_ = a[0:]
+	_ = a[1:10]
+	_ = a[2:len(a)]
+	_ = a[3:(len(a))]
+	_ = a[len(a) : len(a)-1]
+	_ = a[0:len(b)]
+
+	_ = a[:]
+	_ = a[:10]
+	_ = a[:len(a)]
+	_ = a[:(len(a))]
+	_ = a[:len(a)-1]
+	_ = a[:len(b)]
+
+	_ = s[0:]
+	_ = s[1:10]
+	_ = s[2:len(s)]
+	_ = s[3:(len(s))]
+	_ = s[len(a) : len(s)-1]
+	_ = s[0:len(b)]
+
+	_ = s[:]
+	_ = s[:10]
+	_ = s[:len(s)]
+	_ = s[:(len(s))]
+	_ = s[:len(s)-1]
+	_ = s[:len(b)]
+
+	_ = t.s[0:]
+	_ = t.s[1:10]
+	_ = t.s[2:len(t.s)]
+	_ = t.s[3:(len(t.s))]
+	_ = t.s[len(a) : len(t.s)-1]
+	_ = t.s[0:len(b)]
+
+	_ = t.s[:]
+	_ = t.s[:10]
+	_ = t.s[:len(t.s)]
+	_ = t.s[:(len(t.s))]
+	_ = t.s[:len(t.s)-1]
+	_ = t.s[:len(b)]
+)
+
+func _() {
+	s := s[0:len(s)]
+	_ = s
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin1.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin1.golden
new file mode 100644
index 0000000..ff8b0b7
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin1.golden
@@ -0,0 +1,3 @@
+	if x {
+		y
+	}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin1.golden.gofmt b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin1.golden.gofmt
new file mode 100644
index 0000000..1f88887
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin1.golden.gofmt
@@ -0,0 +1,3 @@
+	if x {
+	y
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin1.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin1.input
new file mode 100644
index 0000000..ff8b0b7
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin1.input
@@ -0,0 +1,3 @@
+	if x {
+		y
+	}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin1.input.gofmt b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin1.input.gofmt
new file mode 100644
index 0000000..1f88887
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin1.input.gofmt
@@ -0,0 +1,3 @@
+	if x {
+	y
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin2.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin2.golden
new file mode 100644
index 0000000..7eb1b54
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin2.golden
@@ -0,0 +1,11 @@
+
+
+var x int
+
+func f() {
+	y := z
+	/* this is a comment */
+	// this is a comment too
+}
+
+
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin2.golden.gofmt b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin2.golden.gofmt
new file mode 100644
index 0000000..85e8003
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin2.golden.gofmt
@@ -0,0 +1,10 @@
+
+
+
+var x int
+
+func f() {
+	y := z
+}
+
+
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin2.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin2.input
new file mode 100644
index 0000000..99defd2
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin2.input
@@ -0,0 +1,11 @@
+
+
+var x int
+
+
+func f() { y := z
+	/* this is a comment */
+	// this is a comment too
+}
+
+
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin2.input.gofmt b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin2.input.gofmt
new file mode 100644
index 0000000..7eb1b54
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin2.input.gofmt
@@ -0,0 +1,11 @@
+
+
+var x int
+
+func f() {
+	y := z
+	/* this is a comment */
+	// this is a comment too
+}
+
+
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin3.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin3.golden
new file mode 100644
index 0000000..1bf2f5a
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin3.golden
@@ -0,0 +1,6 @@
+
+		/* note: no newline at end of file */
+		for i := 0; i < 10; i++ {
+			s += i
+		}
+	
\ No newline at end of file
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin3.golden.gofmt b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin3.golden.gofmt
new file mode 100644
index 0000000..b4d1d46
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin3.golden.gofmt
@@ -0,0 +1,7 @@
+
+
+		/* note: no newline at end of file */
+		for i := 0; i < 10; i++ {
+			s += i
+		}
+	
\ No newline at end of file
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin3.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin3.input
new file mode 100644
index 0000000..d963bd0
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin3.input
@@ -0,0 +1,4 @@
+
+		/* note: no newline at end of file */
+		for i := 0; i < 10; i++ { s += i }
+	
\ No newline at end of file
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin3.input.gofmt b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin3.input.gofmt
new file mode 100644
index 0000000..b4d1d46
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin3.input.gofmt
@@ -0,0 +1,7 @@
+
+
+		/* note: no newline at end of file */
+		for i := 0; i < 10; i++ {
+			s += i
+		}
+	
\ No newline at end of file
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin4.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin4.golden
new file mode 100644
index 0000000..5f73435
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin4.golden
@@ -0,0 +1,3 @@
+	// comment
+
+	i := 0
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin4.golden.gofmt b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin4.golden.gofmt
new file mode 100644
index 0000000..5f73435
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin4.golden.gofmt
@@ -0,0 +1,3 @@
+	// comment
+
+	i := 0
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin4.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin4.input
new file mode 100644
index 0000000..f02a54f
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin4.input
@@ -0,0 +1,3 @@
+	// comment
+	
+	i := 0
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin4.input.gofmt b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin4.input.gofmt
new file mode 100644
index 0000000..5f73435
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/stdin4.input.gofmt
@@ -0,0 +1,3 @@
+	// comment
+
+	i := 0
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/typeswitch.golden b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/typeswitch.golden
new file mode 100644
index 0000000..2b1905e
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/typeswitch.golden
@@ -0,0 +1,60 @@
+/*
+	Parenthesized type switch expressions originally
+	accepted by gofmt must continue to be rewritten
+	into the correct unparenthesized form.
+
+	Only type-switches that didn't declare a variable
+	in the type switch type assertion and which
+	contained only "expression-like" (named) types in their
+	cases were permitted to have their type assertion parenthesized
+	by go/parser (due to a weak predicate in the parser). All others
+	were rejected always, either with a syntax error in the
+	type switch header or in the case.
+
+	See also issue 4470.
+*/
+package p
+
+func f() {
+	var x interface{}
+	switch x.(type) { // should remain the same
+	}
+	switch x.(type) { // should become: switch x.(type) {
+	}
+
+	switch x.(type) { // should remain the same
+	case int:
+	}
+	switch x.(type) { // should become: switch x.(type) {
+	case int:
+	}
+
+	switch x.(type) { // should remain the same
+	case []int:
+	}
+
+	// Parenthesized (x.(type)) in type switches containing cases
+	// with unnamed (literal) types were never permitted by gofmt;
+	// thus there won't be any code in the wild using this style if
+	// the code was gofmt-ed.
+	/*
+		switch (x.(type)) {
+		case []int:
+		}
+	*/
+
+	switch t := x.(type) { // should remain the same
+	default:
+		_ = t
+	}
+
+	// Parenthesized (x.(type)) in type switches declaring a variable
+	// were never permitted by gofmt; thus there won't be any code in
+	// the wild using this style if the code was gofmt-ed.
+	/*
+		switch t := (x.(type)) {
+		default:
+			_ = t
+		}
+	*/
+}
diff --git a/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/typeswitch.input b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/typeswitch.input
new file mode 100644
index 0000000..8f8cba9
--- /dev/null
+++ b/third_party/gofrontend/libgo/go/cmd/gofmt/testdata/typeswitch.input
@@ -0,0 +1,60 @@
+/*
+	Parenthesized type switch expressions originally
+	accepted by gofmt must continue to be rewritten
+	into the correct unparenthesized form.
+
+	Only type-switches that didn't declare a variable
+	in the type switch type assertion and which
+	contained only "expression-like" (named) types in their
+	cases were permitted to have their type assertion parenthesized
+	by go/parser (due to a weak predicate in the parser). All others
+	were rejected always, either with a syntax error in the
+	type switch header or in the case.
+
+	See also issue 4470.
+*/
+package p
+
+func f() {
+	var x interface{}
+	switch x.(type) { // should remain the same
+	}
+	switch (x.(type)) { // should become: switch x.(type) {
+	}
+
+	switch x.(type) { // should remain the same
+	case int:
+	}
+	switch (x.(type)) { // should become: switch x.(type) {
+	case int:
+	}
+
+	switch x.(type) { // should remain the same
+	case []int:
+	}
+
+	// Parenthesized (x.(type)) in type switches containing cases
+	// with unnamed (literal) types were never permitted by gofmt;
+	// thus there won't be any code in the wild using this style if
+	// the code was gofmt-ed.
+	/*
+	switch (x.(type)) {
+	case []int:
+	}
+	*/
+
+	switch t := x.(type) { // should remain the same
+	default:
+		_ = t
+	}
+
+	// Parenthesized (x.(type)) in type switches declaring a variable
+	// were never permitted by gofmt; thus there won't be any code in
+	// the wild using this style if the code was gofmt-ed.
+	/*
+	switch t := (x.(type)) {
+	default:
+		_ = t
+	}
+	*/
+}
diff --git a/third_party/gofrontend/libgo/go/go/build/build.go b/third_party/gofrontend/libgo/go/go/build/build.go
index 1032c93..5fe7dcb 100644
--- a/third_party/gofrontend/libgo/go/go/build/build.go
+++ b/third_party/gofrontend/libgo/go/go/build/build.go
@@ -268,6 +268,8 @@
 	"linux/386":       true,
 	"linux/amd64":     true,
 	"linux/arm":       true,
+	"linux/ppc64":     true,
+	"linux/ppc64le":   true,
 	"linux/s390":      true,
 	"linux/s390x":     true,
 	"netbsd/386":      true,
@@ -1196,8 +1198,15 @@
 	}
 }
 
-// ToolDir is the directory containing build tools.
-var ToolDir = filepath.Join(runtime.GOROOT(), "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH)
+func getToolDir() string {
+	if runtime.Compiler == "gccgo" {
+		return runtime.GCCGOTOOLDIR
+	} else {
+		return filepath.Join(runtime.GOROOT(), "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH)
+	}
+}
+
+var ToolDir = getToolDir()
 
 // IsLocalImport reports whether the import path is
 // a local import path, like ".", "..", "./foo", or "../foo".
@@ -1218,6 +1227,8 @@
 		return "5", nil
 	case "arm64":
 		return "7", nil
+	case "ppc64", "ppc64le":
+		return "9", nil
 	}
 	return "", errors.New("unsupported GOARCH " + goarch)
 }
diff --git a/third_party/gofrontend/libgo/go/runtime/extern.go b/third_party/gofrontend/libgo/go/runtime/extern.go
index 333d4fd..393984c 100644
--- a/third_party/gofrontend/libgo/go/runtime/extern.go
+++ b/third_party/gofrontend/libgo/go/runtime/extern.go
@@ -201,5 +201,8 @@
 const GOOS string = theGoos
 
 // GOARCH is the running program's architecture target:
-// 386, amd64, arm or arm64.
+// 386, amd64, arm, arm64, ppc64, ppc64le.
 const GOARCH string = theGoarch
+
+// GCCGOTOOLDIR is the Tool Dir for the gccgo build
+const GCCGOTOOLDIR string = theGccgoToolDir
diff --git a/third_party/gofrontend/libgo/go/testing/testing.go b/third_party/gofrontend/libgo/go/testing/testing.go
index 8078ba7..1b7360a 100644
--- a/third_party/gofrontend/libgo/go/testing/testing.go
+++ b/third_party/gofrontend/libgo/go/testing/testing.go
@@ -117,6 +117,26 @@
 // The entire test file is presented as the example when it contains a single
 // example function, at least one other function, type, variable, or constant
 // declaration, and no test or benchmark functions.
+//
+// Main
+//
+// It is sometimes necessary for a test program to do extra setup or teardown
+// before or after testing. It is also sometimes necessary for a test to control
+// which code runs on the main thread. To support these and other cases,
+// if a test file contains a function:
+//
+//	func TestMain(m *testing.M)
+//
+// then the generated test will call TestMain(m) instead of running the tests
+// directly. TestMain runs in the main goroutine and can do whatever setup
+// and teardown is necessary around a call to m.Run. It should then call
+// os.Exit with the result of m.Run.
+//
+// The minimal implementation of TestMain is:
+//
+//	func TestMain(m *testing.M) { os.Exit(m.Run()) }
+//
+// In effect, that is the implementation used when no TestMain is explicitly defined.
 package testing
 
 import (
@@ -426,23 +446,49 @@
 // An internal function but exported because it is cross-package; part of the implementation
 // of the "go test" command.
 func Main(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) {
+	os.Exit(MainStart(matchString, tests, benchmarks, examples).Run())
+}
+
+// M is a type passed to a TestMain function to run the actual tests.
+type M struct {
+	matchString func(pat, str string) (bool, error)
+	tests       []InternalTest
+	benchmarks  []InternalBenchmark
+	examples    []InternalExample
+}
+
+// MainStart is meant for use by tests generated by 'go test'.
+// It is not meant to be called directly and is not subject to the Go 1 compatibility document.
+// It may change signature from release to release.
+func MainStart(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) *M {
+	return &M{
+		matchString: matchString,
+		tests:       tests,
+		benchmarks:  benchmarks,
+		examples:    examples,
+	}
+}
+
+// Run runs the tests. It returns an exit code to pass to os.Exit.
+func (m *M) Run() int {
 	flag.Parse()
 	parseCpuList()
 
 	before()
 	startAlarm()
-	haveExamples = len(examples) > 0
-	testOk := RunTests(matchString, tests)
-	exampleOk := RunExamples(matchString, examples)
+	haveExamples = len(m.examples) > 0
+	testOk := RunTests(m.matchString, m.tests)
+	exampleOk := RunExamples(m.matchString, m.examples)
 	stopAlarm()
 	if !testOk || !exampleOk {
 		fmt.Println("FAIL")
 		after()
-		os.Exit(1)
+		return 1
 	}
 	fmt.Println("PASS")
-	RunBenchmarks(matchString, benchmarks)
+	RunBenchmarks(m.matchString, m.benchmarks)
 	after()
+	return 0
 }
 
 func (t *T) report() {
diff --git a/third_party/gofrontend/libgo/merge.sh b/third_party/gofrontend/libgo/merge.sh
index e579ac7..fb0d1af 100755
--- a/third_party/gofrontend/libgo/merge.sh
+++ b/third_party/gofrontend/libgo/merge.sh
@@ -163,6 +163,36 @@
   done
 done
 
+cmdlist="cgo go gofmt"
+for c in $cmdlist; do
+  (cd ${NEWDIR}/src/cmd/$c && find . -name '*.go' -print) | while read f; do
+    oldfile=${OLDDIR}/src/cmd/$c/$f
+    newfile=${NEWDIR}/src/cmd/$c/$f
+    libgofile=go/cmd/$c/$f
+    merge $f ${oldfile} ${newfile} ${libgofile}
+  done
+
+  (cd ${NEWDIR}/src/cmd/$c && find . -name testdata -print) | while read d; do
+    oldtd=${OLDDIR}/src/cmd/$c/$d
+    newtd=${NEWDIR}/src/cmd/$c/$d
+    libgotd=go/cmd/$c/$d
+    if ! test -d ${oldtd}; then
+      continue
+    fi
+    (cd ${oldtd} && hg status -A .) | while read f; do
+      if test "`basename $f`" = ".hgignore"; then
+        continue
+      fi
+      f=`echo $f | sed -e 's/^..//'`
+      name=$d/$f
+      oldfile=${oldtd}/$f
+      newfile=${newtd}/$f
+      libgofile=${libgotd}/$f
+      merge ${name} ${oldfile} ${newfile} ${libgofile}
+    done
+  done
+done
+
 runtime="chan.goc chan.h cpuprof.goc env_posix.c heapdump.c lock_futex.c lfstack.goc lock_sema.c mcache.c mcentral.c mfixalloc.c mgc0.c mgc0.h mheap.c msize.c netpoll.goc netpoll_epoll.c netpoll_kqueue.c netpoll_stub.c panic.c print.c proc.c race.h rdebug.goc runtime.c runtime.h signal_unix.c signal_unix.h malloc.h malloc.goc mprof.goc parfor.c runtime1.goc sema.goc sigqueue.goc string.goc time.goc"
 for f in $runtime; do
   merge_c $f $f
diff --git a/third_party/gofrontend/libgo/runtime/chan.goc b/third_party/gofrontend/libgo/runtime/chan.goc
index 9504369..378f57f 100644
--- a/third_party/gofrontend/libgo/runtime/chan.goc
+++ b/third_party/gofrontend/libgo/runtime/chan.goc
@@ -6,7 +6,6 @@
 #include "runtime.h"
 #include "arch.h"
 #include "go-type.h"
-#include "race.h"
 #include "malloc.h"
 #include "chan.h"
 
@@ -15,7 +14,6 @@
 static	void	dequeueg(WaitQ*);
 static	SudoG*	dequeue(WaitQ*);
 static	void	enqueue(WaitQ*, SudoG*);
-static	void	racesync(Hchan*, SudoG*);
 
 static Hchan*
 makechan(ChanType *t, int64 hint)
@@ -82,6 +80,7 @@
 static bool
 chansend(ChanType *t, Hchan *c, byte *ep, bool block, void *pc)
 {
+	USED(pc);
 	SudoG *sg;
 	SudoG mysg;
 	G* gp;
@@ -90,9 +89,6 @@
 
 	g = runtime_g();
 
-	if(raceenabled)
-		runtime_racereadobjectpc(ep, t->__element_type, runtime_getcallerpc(&t), chansend);
-
 	if(c == nil) {
 		USED(t);
 		if(!block)
@@ -116,8 +112,6 @@
 	}
 
 	runtime_lock(&c->lock);
-	if(raceenabled)
-		runtime_racereadpc(c, pc, chansend);
 	if(c->closed)
 		goto closed;
 
@@ -126,8 +120,6 @@
 
 	sg = dequeue(&c->recvq);
 	if(sg != nil) {
-		if(raceenabled)
-			racesync(c, sg);
 		runtime_unlock(&c->lock);
 
 		gp = sg->g;
@@ -183,11 +175,6 @@
 		goto asynch;
 	}
 
-	if(raceenabled) {
-		runtime_raceacquire(chanbuf(c, c->sendx));
-		runtime_racerelease(chanbuf(c, c->sendx));
-	}
-
 	runtime_memmove(chanbuf(c, c->sendx), ep, c->elemsize);
 	if(++c->sendx == c->dataqsiz)
 		c->sendx = 0;
@@ -225,8 +212,6 @@
 	if(runtime_gcwaiting())
 		runtime_gosched();
 
-	// raceenabled: don't need to check ep, as it is always on the stack.
-
 	if(debug)
 		runtime_printf("chanrecv: chan=%p\n", c);
 
@@ -256,8 +241,6 @@
 
 	sg = dequeue(&c->sendq);
 	if(sg != nil) {
-		if(raceenabled)
-			racesync(c, sg);
 		runtime_unlock(&c->lock);
 
 		if(ep != nil)
@@ -319,11 +302,6 @@
 		goto asynch;
 	}
 
-	if(raceenabled) {
-		runtime_raceacquire(chanbuf(c, c->recvx));
-		runtime_racerelease(chanbuf(c, c->recvx));
-	}
-
 	if(ep != nil)
 		runtime_memmove(ep, chanbuf(c, c->recvx), c->elemsize);
 	runtime_memclr(chanbuf(c, c->recvx), c->elemsize);
@@ -352,8 +330,6 @@
 		runtime_memclr(ep, c->elemsize);
 	if(received != nil)
 		*received = false;
-	if(raceenabled)
-		runtime_raceacquire(c);
 	runtime_unlock(&c->lock);
 	if(mysg.releasetime > 0)
 		runtime_blockevent(mysg.releasetime - t0, 2);
@@ -789,8 +765,6 @@
 			break;
 
 		case CaseSend:
-			if(raceenabled)
-				runtime_racereadpc(c, runtime_selectgo, chansend);
 			if(c->closed)
 				goto sclose;
 			if(c->dataqsiz > 0) {
@@ -874,24 +848,11 @@
 			*cas->receivedp = true;
 	}
 
-	if(raceenabled) {
-		if(cas->kind == CaseRecv && cas->sg.elem != nil)
-			runtime_racewriteobjectpc(cas->sg.elem, c->elemtype, selectgo, chanrecv);
-		else if(cas->kind == CaseSend)
-			runtime_racereadobjectpc(cas->sg.elem, c->elemtype, selectgo, chansend);
-	}
-
 	selunlock(sel);
 	goto retc;
 
 asyncrecv:
 	// can receive from buffer
-	if(raceenabled) {
-		if(cas->sg.elem != nil)
-			runtime_racewriteobjectpc(cas->sg.elem, c->elemtype, selectgo, chanrecv);
-		runtime_raceacquire(chanbuf(c, c->recvx));
-		runtime_racerelease(chanbuf(c, c->recvx));
-	}
 	if(cas->receivedp != nil)
 		*cas->receivedp = true;
 	if(cas->sg.elem != nil)
@@ -914,11 +875,6 @@
 
 asyncsend:
 	// can send to buffer
-	if(raceenabled) {
-		runtime_raceacquire(chanbuf(c, c->sendx));
-		runtime_racerelease(chanbuf(c, c->sendx));
-		runtime_racereadobjectpc(cas->sg.elem, c->elemtype, selectgo, chansend);
-	}
 	runtime_memmove(chanbuf(c, c->sendx), cas->sg.elem, c->elemsize);
 	if(++c->sendx == c->dataqsiz)
 		c->sendx = 0;
@@ -937,11 +893,6 @@
 
 syncrecv:
 	// can receive from sleeping sender (sg)
-	if(raceenabled) {
-		if(cas->sg.elem != nil)
-			runtime_racewriteobjectpc(cas->sg.elem, c->elemtype, selectgo, chanrecv);
-		racesync(c, sg);
-	}
 	selunlock(sel);
 	if(debug)
 		runtime_printf("syncrecv: sel=%p c=%p o=%d\n", sel, c, o);
@@ -963,16 +914,10 @@
 		*cas->receivedp = false;
 	if(cas->sg.elem != nil)
 		runtime_memclr(cas->sg.elem, c->elemsize);
-	if(raceenabled)
-		runtime_raceacquire(c);
 	goto retc;
 
 syncsend:
 	// can send to sleeping receiver (sg)
-	if(raceenabled) {
-		runtime_racereadobjectpc(cas->sg.elem, c->elemtype, selectgo, chansend);
-		racesync(c, sg);
-	}
 	selunlock(sel);
 	if(debug)
 		runtime_printf("syncsend: sel=%p c=%p o=%d\n", sel, c, o);
@@ -1062,6 +1007,7 @@
 static void
 closechan(Hchan *c, void *pc)
 {
+	USED(pc);
 	SudoG *sg;
 	G* gp;
 
@@ -1076,12 +1022,6 @@
 		runtime_unlock(&c->lock);
 		runtime_panicstring("close of closed channel");
 	}
-
-	if(raceenabled) {
-		runtime_racewritepc(c, pc, runtime_closechan);
-		runtime_racerelease(c);
-	}
-
 	c->closed = true;
 
 	// release all readers
@@ -1194,12 +1134,3 @@
 	q->last->link = sgp;
 	q->last = sgp;
 }
-
-static void
-racesync(Hchan *c, SudoG *sg)
-{
-	runtime_racerelease(chanbuf(c, 0));
-	runtime_raceacquireg(sg->g, chanbuf(c, 0));
-	runtime_racereleaseg(sg->g, chanbuf(c, 0));
-	runtime_raceacquire(chanbuf(c, 0));
-}
diff --git a/third_party/gofrontend/libgo/runtime/go-map-delete.c b/third_party/gofrontend/libgo/runtime/go-map-delete.c
index de8b046..aff25d1 100644
--- a/third_party/gofrontend/libgo/runtime/go-map-delete.c
+++ b/third_party/gofrontend/libgo/runtime/go-map-delete.c
@@ -35,7 +35,10 @@
   key_descriptor = descriptor->__map_descriptor->__key_type;
   key_offset = descriptor->__key_offset;
   key_size = key_descriptor->__size;
-  __go_assert (key_size != 0 && key_size != -1UL);
+  if (key_size == 0)
+    return;
+
+  __go_assert (key_size != -1UL);
   equalfn = key_descriptor->__equalfn;
 
   key_hash = key_descriptor->__hashfn (key, key_size);
diff --git a/third_party/gofrontend/libgo/runtime/malloc.goc b/third_party/gofrontend/libgo/runtime/malloc.goc
index b2c4eea..b05ebe6 100644
--- a/third_party/gofrontend/libgo/runtime/malloc.goc
+++ b/third_party/gofrontend/libgo/runtime/malloc.goc
@@ -16,7 +16,6 @@
 #include "malloc.h"
 #include "interface.h"
 #include "go-type.h"
-#include "race.h"
 
 // Map gccgo field names to gc field names.
 // Eface aka __go_empty_interface.
@@ -249,9 +248,6 @@
 	if(UseSpanType && !(flag & FlagNoScan) && typ != 0)
 		settype(s, v, typ);
 
-	if(raceenabled)
-		runtime_racemalloc(v, size);
-
 	if(runtime_debug.allocfreetrace)
 		runtime_tracealloc(v, size, typ);
 
@@ -697,8 +693,6 @@
 		h->arena_used += n;
 		runtime_MHeap_MapBits(h);
 		runtime_MHeap_MapSpans(h);
-		if(raceenabled)
-			runtime_racemapshadow(p, n);
 		
 		if(((uintptr)p & (PageSize-1)) != 0)
 			runtime_throw("misrounded allocation in MHeap_SysAlloc");
@@ -732,8 +726,6 @@
 			h->arena_end = p_end;
 		runtime_MHeap_MapBits(h);
 		runtime_MHeap_MapSpans(h);
-		if(raceenabled)
-			runtime_racemapshadow(p, n);
 	}
 	
 	if(((uintptr)p & (PageSize-1)) != 0)
diff --git a/third_party/gofrontend/libgo/runtime/mgc0.c b/third_party/gofrontend/libgo/runtime/mgc0.c
index 3732b60..1e75c2d 100644
--- a/third_party/gofrontend/libgo/runtime/mgc0.c
+++ b/third_party/gofrontend/libgo/runtime/mgc0.c
@@ -57,7 +57,6 @@
 #include "malloc.h"
 #include "mgc0.h"
 #include "chan.h"
-#include "race.h"
 #include "go-type.h"
 
 // Map gccgo field names to gc field names.
@@ -2507,8 +2506,6 @@
 			continue;
 		}
 		runtime_unlock(&finlock);
-		if(raceenabled)
-			runtime_racefingo();
 		for(; fb; fb=next) {
 			next = fb->next;
 			for(i=0; i<(uint32)fb->cnt; i++) {
diff --git a/third_party/gofrontend/libgo/runtime/proc.c b/third_party/gofrontend/libgo/runtime/proc.c
index 146f285..28896ce 100644
--- a/third_party/gofrontend/libgo/runtime/proc.c
+++ b/third_party/gofrontend/libgo/runtime/proc.c
@@ -18,7 +18,6 @@
 #include "arch.h"
 #include "defs.h"
 #include "malloc.h"
-#include "race.h"
 #include "go-type.h"
 #include "go-defer.h"
 
@@ -51,7 +50,7 @@
 #if defined(USING_SPLIT_STACK) && defined(LINKER_SUPPORTS_SPLIT_STACK)
 # define StackMin PTHREAD_STACK_MIN
 #else
-# define StackMin 2 * 1024 * 1024
+# define StackMin ((sizeof(char *) < 8) ? 2 * 1024 * 1024 : 4 * 1024 * 1024)
 #endif
 
 uintptr runtime_stacks_sys;
@@ -462,9 +461,6 @@
 
 	// Can not enable GC until all roots are registered.
 	// mstats.enablegc = 1;
-
-	// if(raceenabled)
-	//	g->racectx = runtime_raceinit();
 }
 
 extern void main_init(void) __asm__ (GOSYM_PREFIX "__go_init_main");
@@ -528,8 +524,6 @@
 	mstats.enablegc = 1;
 
 	main_main();
-	if(raceenabled)
-		runtime_racefini();
 
 	// Make racy client program work: if panicking on
 	// another goroutine at the same time as main returns,
@@ -1150,6 +1144,7 @@
 	__splitstack_getcontext(&g->stack_context[0]);
 #else
 	g->gcinitial_sp = &mp;
+	g->gcstack = nil;
 	g->gcstack_size = 0;
 	g->gcnext_sp = &mp;
 #endif
@@ -1251,6 +1246,8 @@
 	runtime_setmg(nil, nil);
 
 	mp->curg->status = Gdead;
+	mp->curg->gcstack = nil;
+	mp->curg->gcnext_sp = nil;
 
 	mnext = lockextra(true);
 	mp->schedlink = mnext;
@@ -1845,8 +1842,6 @@
 {
 	if(g->status != Grunning)
 		runtime_throw("bad g status");
-	if(raceenabled)
-		runtime_racegoend();
 	runtime_mcall(goexit0);
 }
 
diff --git a/third_party/gofrontend/libgo/runtime/race.h b/third_party/gofrontend/libgo/runtime/race.h
deleted file mode 100644
index 0f4718a..0000000
--- a/third_party/gofrontend/libgo/runtime/race.h
+++ /dev/null
@@ -1,34 +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.
-
-// Definitions related to data race detection.
-
-#ifdef RACE
-enum { raceenabled = 1 };
-#else
-enum { raceenabled = 0 };
-#endif
-
-// Initialize race detection subsystem.
-uintptr	runtime_raceinit(void);
-// Finalize race detection subsystem, does not return.
-void	runtime_racefini(void);
-
-void	runtime_racemapshadow(void *addr, uintptr size);
-void	runtime_racemalloc(void *p, uintptr sz);
-uintptr	runtime_racegostart(void *pc);
-void	runtime_racegoend(void);
-void	runtime_racewritepc(void *addr, void *callpc, void *pc);
-void	runtime_racereadpc(void *addr, void *callpc, void *pc);
-void	runtime_racewriterangepc(void *addr, uintptr sz, void *callpc, void *pc);
-void	runtime_racereadrangepc(void *addr, uintptr sz, void *callpc, void *pc);
-void	runtime_racereadobjectpc(void *addr, const Type *t, void *callpc, void *pc);
-void	runtime_racewriteobjectpc(void *addr, const Type *t, void *callpc, void *pc);
-void	runtime_racefingo(void);
-void	runtime_raceacquire(void *addr);
-void	runtime_raceacquireg(G *gp, void *addr);
-void	runtime_racerelease(void *addr);
-void	runtime_racereleaseg(G *gp, void *addr);
-void	runtime_racereleasemerge(void *addr);
-void	runtime_racereleasemergeg(G *gp, void *addr);
diff --git a/third_party/gofrontend/libgo/runtime/string.goc b/third_party/gofrontend/libgo/runtime/string.goc
index f656318..0ad180b 100644
--- a/third_party/gofrontend/libgo/runtime/string.goc
+++ b/third_party/gofrontend/libgo/runtime/string.goc
@@ -7,7 +7,6 @@
 #include "arch.h"
 #include "malloc.h"
 #include "go-string.h"
-#include "race.h"
 
 #define charntorune(pv, str, len) __go_get_rune(str, len, pv)
 
diff --git a/third_party/gofrontend/libgo/runtime/time.goc b/third_party/gofrontend/libgo/runtime/time.goc
index e300215..a607c4a 100644
--- a/third_party/gofrontend/libgo/runtime/time.goc
+++ b/third_party/gofrontend/libgo/runtime/time.goc
@@ -12,7 +12,6 @@
 #include "defs.h"
 #include "arch.h"
 #include "malloc.h"
-#include "race.h"
 
 enum {
 	debug = 0,
@@ -42,8 +41,6 @@
 
 // startTimer adds t to the timer heap.
 func startTimer(t *Timer) {
-	if(raceenabled)
-		runtime_racerelease(t);
 	runtime_addtimer(t);
 }
 
@@ -237,8 +234,6 @@
 			f = (void*)t->fv->fn;
 			arg = t->arg;
 			runtime_unlock(&timers.lock);
-			if(raceenabled)
-				runtime_raceacquire(t);
 			__go_set_closure(fv);
 			f(now, arg);
 
diff --git a/update_third_party.sh b/update_third_party.sh
index fe9437a..a35d315 100755
--- a/update_third_party.sh
+++ b/update_third_party.sh
@@ -1,7 +1,7 @@
 #!/bin/sh -e
 
 gofrontendrepo=https://code.google.com/p/gofrontend
-gofrontendrev=2a85649c19e1
+gofrontendrev=0fde0b6a7eb2
 
 gccrepo=svn://gcc.gnu.org/svn/gcc/trunk
 gccrev=216268
@@ -25,7 +25,7 @@
 # Apply a diff that eliminates use of the unnamed struct extension beyond what
 # -fms-extensions supports.
 (cd third_party/gofrontend && patch -p1) < libgo-noext.diff
-find third_party/gofrontend -name '*.orig' | xargs rm
+find third_party/gofrontend -name '*.orig' -exec rm \{\} \;
 
 # Remove GPL licensed files.
 rm \