diff --git a/src/cmd/asm/internal/flags/flags.go b/src/cmd/asm/internal/flags/flags.go
index e8535ae..1df9df9 100644
--- a/src/cmd/asm/internal/flags/flags.go
+++ b/src/cmd/asm/internal/flags/flags.go
@@ -25,8 +25,6 @@
 	SymABIs    = flag.Bool("gensymabis", false, "write symbol ABI information to output file, don't assemble")
 	Importpath = flag.String("p", "", "set expected package import to path")
 	Spectre    = flag.String("spectre", "", "enable spectre mitigations in `list` (all, ret)")
-
-	Go115Newobj = flag.Bool("go115newobj", true, "use new object file format")
 )
 
 var (
diff --git a/src/cmd/asm/main.go b/src/cmd/asm/main.go
index 9ca9797..71ee041 100644
--- a/src/cmd/asm/main.go
+++ b/src/cmd/asm/main.go
@@ -40,7 +40,6 @@
 	}
 	ctxt.Flag_dynlink = *flags.Dynlink
 	ctxt.Flag_shared = *flags.Shared || *flags.Dynlink
-	ctxt.Flag_go115newobj = *flags.Go115Newobj
 	ctxt.IsAsm = true
 	switch *flags.Spectre {
 	default:
diff --git a/src/cmd/compile/internal/gc/iexport.go b/src/cmd/compile/internal/gc/iexport.go
index 35b8d98..32cc50f 100644
--- a/src/cmd/compile/internal/gc/iexport.go
+++ b/src/cmd/compile/internal/gc/iexport.go
@@ -997,18 +997,16 @@
 }
 
 func (w *exportWriter) symIdx(s *types.Sym) {
-	if Ctxt.Flag_go115newobj {
-		lsym := s.Linksym()
-		if lsym.PkgIdx > goobj2.PkgIdxSelf || (lsym.PkgIdx == goobj2.PkgIdxInvalid && !lsym.Indexed()) || s.Linkname != "" {
-			// Don't export index for non-package symbols, linkname'd symbols,
-			// and symbols without an index. They can only be referenced by
-			// name.
-			w.int64(-1)
-		} else {
-			// For a defined symbol, export its index.
-			// For re-exporting an imported symbol, pass its index through.
-			w.int64(int64(lsym.SymIdx))
-		}
+	lsym := s.Linksym()
+	if lsym.PkgIdx > goobj2.PkgIdxSelf || (lsym.PkgIdx == goobj2.PkgIdxInvalid && !lsym.Indexed()) || s.Linkname != "" {
+		// Don't export index for non-package symbols, linkname'd symbols,
+		// and symbols without an index. They can only be referenced by
+		// name.
+		w.int64(-1)
+	} else {
+		// For a defined symbol, export its index.
+		// For re-exporting an imported symbol, pass its index through.
+		w.int64(int64(lsym.SymIdx))
 	}
 }
 
diff --git a/src/cmd/compile/internal/gc/iimport.go b/src/cmd/compile/internal/gc/iimport.go
index f3e65ff..7c0764c 100644
--- a/src/cmd/compile/internal/gc/iimport.go
+++ b/src/cmd/compile/internal/gc/iimport.go
@@ -696,16 +696,14 @@
 }
 
 func (r *importReader) symIdx(s *types.Sym) {
-	if Ctxt.Flag_go115newobj {
-		lsym := s.Linksym()
-		idx := int32(r.int64())
-		if idx != -1 {
-			if s.Linkname != "" {
-				Fatalf("bad index for linknamed symbol: %v %d\n", lsym, idx)
-			}
-			lsym.SymIdx = idx
-			lsym.Set(obj.AttrIndexed, true)
+	lsym := s.Linksym()
+	idx := int32(r.int64())
+	if idx != -1 {
+		if s.Linkname != "" {
+			Fatalf("bad index for linknamed symbol: %v %d\n", lsym, idx)
 		}
+		lsym.SymIdx = idx
+		lsym.Set(obj.AttrIndexed, true)
 	}
 }
 
diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go
index 756cdbd..ba40582 100644
--- a/src/cmd/compile/internal/gc/main.go
+++ b/src/cmd/compile/internal/gc/main.go
@@ -281,7 +281,6 @@
 	flag.StringVar(&benchfile, "bench", "", "append benchmark times to `file`")
 	flag.BoolVar(&smallFrames, "smallframes", false, "reduce the size limit for stack allocated objects")
 	flag.BoolVar(&Ctxt.UseBASEntries, "dwarfbasentries", Ctxt.UseBASEntries, "use base address selection entries in DWARF")
-	flag.BoolVar(&Ctxt.Flag_go115newobj, "go115newobj", true, "use new object file format")
 	flag.StringVar(&jsonLogOpt, "json", "", "version,destination for JSON compiler/optimizer logging")
 
 	objabi.Flagparse(usage)
@@ -315,7 +314,7 @@
 	// Record flags that affect the build result. (And don't
 	// record flags that don't, since that would cause spurious
 	// changes in the binary.)
-	recordFlags("B", "N", "l", "msan", "race", "shared", "dynlink", "dwarflocationlists", "dwarfbasentries", "smallframes", "spectre", "go115newobj")
+	recordFlags("B", "N", "l", "msan", "race", "shared", "dynlink", "dwarflocationlists", "dwarfbasentries", "smallframes", "spectre")
 
 	if smallFrames {
 		maxStackVarSize = 128 * 1024
diff --git a/src/cmd/internal/dwarf/dwarf.go b/src/cmd/internal/dwarf/dwarf.go
index db01399..6ab8363 100644
--- a/src/cmd/internal/dwarf/dwarf.go
+++ b/src/cmd/internal/dwarf/dwarf.go
@@ -18,21 +18,9 @@
 	"strings"
 )
 
-// TODO(go115newobj): clean up. Some constant prefixes here are no longer
-// needed in the new object files.
-
 // InfoPrefix is the prefix for all the symbols containing DWARF info entries.
 const InfoPrefix = "go.info."
 
-// RangePrefix is the prefix for all the symbols containing DWARF location lists.
-const LocPrefix = "go.loc."
-
-// RangePrefix is the prefix for all the symbols containing DWARF range lists.
-const RangePrefix = "go.range."
-
-// DebugLinesPrefix is the prefix for all the symbols containing DWARF debug_line information from the compiler.
-const DebugLinesPrefix = "go.debuglines."
-
 // ConstInfoPrefix is the prefix for all symbols containing DWARF info
 // entries that contain constants.
 const ConstInfoPrefix = "go.constinfo."
diff --git a/src/cmd/internal/goobj/goobj_test.go b/src/cmd/internal/goobj/goobj_test.go
index 9f827c6..4acd30e 100644
--- a/src/cmd/internal/goobj/goobj_test.go
+++ b/src/cmd/internal/goobj/goobj_test.go
@@ -151,12 +151,9 @@
 	return nil
 }
 
-// Check that a symbol has a given name, accepting both
-// new and old objects.
-// TODO(go115newobj): remove.
+// Check that a symbol has a given name.
 func matchSymName(symname, want string) bool {
-	return symname == want ||
-		strings.HasPrefix(symname, want+"#") // new style, with index
+	return strings.HasPrefix(symname, want+"#") // new style, with index
 }
 
 func TestParseGoobj(t *testing.T) {
diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go
index 32906a3..1b54df2 100644
--- a/src/cmd/internal/obj/link.go
+++ b/src/cmd/internal/obj/link.go
@@ -656,7 +656,6 @@
 	Flag_linkshared    bool
 	Flag_optimize      bool
 	Flag_locationlists bool
-	Flag_go115newobj   bool // use new object file format
 	Retpoline          bool // emit use of retpoline stubs for indirect jmp/call
 	Bso                *bufio.Writer
 	Pathname           string
diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go
index 6d7f42e..6701b9b 100644
--- a/src/cmd/internal/obj/objfile.go
+++ b/src/cmd/internal/obj/objfile.go
@@ -2,234 +2,18 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Writing of Go object files.
-
 package obj
 
 import (
-	"bufio"
-	"cmd/internal/bio"
 	"cmd/internal/dwarf"
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"fmt"
 	"io"
-	"log"
-	"path/filepath"
 	"sort"
-	"strings"
 	"sync"
 )
 
-// objWriter writes Go object files.
-type objWriter struct {
-	wr   *bufio.Writer
-	ctxt *Link
-	// Temporary buffer for zigzag int writing.
-	varintbuf [10]uint8
-
-	// Number of objects written of each type.
-	nRefs     int
-	nData     int
-	nReloc    int
-	nPcdata   int
-	nFuncdata int
-	nFile     int
-
-	pkgpath string // the package import path (escaped), "" if unknown
-}
-
-func (w *objWriter) addLengths(s *LSym) {
-	w.nData += len(s.P)
-	w.nReloc += len(s.R)
-
-	if s.Type != objabi.STEXT {
-		return
-	}
-
-	pc := &s.Func.Pcln
-
-	data := 0
-	data += len(pc.Pcsp.P)
-	data += len(pc.Pcfile.P)
-	data += len(pc.Pcline.P)
-	data += len(pc.Pcinline.P)
-	for _, pcd := range pc.Pcdata {
-		data += len(pcd.P)
-	}
-
-	w.nData += data
-	w.nPcdata += len(pc.Pcdata)
-
-	w.nFuncdata += len(pc.Funcdataoff)
-	w.nFile += len(pc.File)
-}
-
-func (w *objWriter) writeLengths() {
-	w.writeInt(int64(w.nData))
-	w.writeInt(int64(w.nReloc))
-	w.writeInt(int64(w.nPcdata))
-	w.writeInt(int64(0)) // TODO: remove at next object file rev
-	w.writeInt(int64(w.nFuncdata))
-	w.writeInt(int64(w.nFile))
-}
-
-func newObjWriter(ctxt *Link, b *bufio.Writer, pkgpath string) *objWriter {
-	return &objWriter{
-		ctxt:    ctxt,
-		wr:      b,
-		pkgpath: objabi.PathToPrefix(pkgpath),
-	}
-}
-
-func WriteObjFile(ctxt *Link, bout *bio.Writer, pkgpath string) {
-	if ctxt.Flag_go115newobj {
-		WriteObjFile2(ctxt, bout, pkgpath)
-		return
-	}
-
-	b := bout.Writer
-	w := newObjWriter(ctxt, b, pkgpath)
-
-	// Magic header
-	w.wr.WriteString("\x00go114ld")
-
-	// Version
-	w.wr.WriteByte(1)
-
-	// Autolib
-	for _, p := range ctxt.Imports {
-		w.writeString(p.Pkg)
-		// This object format ignores p.Fingerprint.
-	}
-	w.writeString("")
-
-	// DWARF File Table
-	fileTable := ctxt.PosTable.DebugLinesFileTable()
-	w.writeInt(int64(len(fileTable)))
-	for _, str := range fileTable {
-		w.writeString(filepath.ToSlash(str))
-	}
-
-	// Symbol references
-	for _, s := range ctxt.Text {
-		w.writeRefs(s)
-		w.addLengths(s)
-	}
-
-	if ctxt.Headtype == objabi.Haix {
-		// Data must be sorted to keep a constant order in TOC symbols.
-		// As they are created during Progedit, two symbols can be switched between
-		// two different compilations. Therefore, BuildID will be different.
-		// TODO: find a better place and optimize to only sort TOC symbols
-		sort.Slice(ctxt.Data, func(i, j int) bool {
-			return ctxt.Data[i].Name < ctxt.Data[j].Name
-		})
-	}
-
-	for _, s := range ctxt.Data {
-		w.writeRefs(s)
-		w.addLengths(s)
-	}
-	for _, s := range ctxt.ABIAliases {
-		w.writeRefs(s)
-		w.addLengths(s)
-	}
-	// End symbol references
-	w.wr.WriteByte(0xff)
-
-	// Lengths
-	w.writeLengths()
-
-	// Data block
-	for _, s := range ctxt.Text {
-		w.wr.Write(s.P)
-		pc := &s.Func.Pcln
-		w.wr.Write(pc.Pcsp.P)
-		w.wr.Write(pc.Pcfile.P)
-		w.wr.Write(pc.Pcline.P)
-		w.wr.Write(pc.Pcinline.P)
-		for _, pcd := range pc.Pcdata {
-			w.wr.Write(pcd.P)
-		}
-	}
-	for _, s := range ctxt.Data {
-		if len(s.P) > 0 {
-			switch s.Type {
-			case objabi.SBSS, objabi.SNOPTRBSS, objabi.STLSBSS:
-				ctxt.Diag("cannot provide data for %v sym %v", s.Type, s.Name)
-			}
-		}
-		w.wr.Write(s.P)
-	}
-
-	// Symbols
-	for _, s := range ctxt.Text {
-		w.writeSym(s)
-	}
-	for _, s := range ctxt.Data {
-		w.writeSym(s)
-	}
-	for _, s := range ctxt.ABIAliases {
-		w.writeSym(s)
-	}
-
-	// Magic footer
-	w.wr.WriteString("\xffgo114ld")
-}
-
-// Symbols are prefixed so their content doesn't get confused with the magic footer.
-const symPrefix = 0xfe
-
-func (w *objWriter) writeRef(s *LSym, isPath bool) {
-	if s == nil || s.RefIdx != 0 {
-		return
-	}
-	w.wr.WriteByte(symPrefix)
-	if isPath {
-		w.writeString(filepath.ToSlash(s.Name))
-	} else if w.pkgpath != "" {
-		// w.pkgpath is already escaped.
-		n := strings.Replace(s.Name, "\"\".", w.pkgpath+".", -1)
-		w.writeString(n)
-	} else {
-		w.writeString(s.Name)
-	}
-	// Write ABI/static information.
-	abi := int64(s.ABI())
-	if s.Static() {
-		abi = -1
-	}
-	w.writeInt(abi)
-	w.nRefs++
-	s.RefIdx = w.nRefs
-}
-
-func (w *objWriter) writeRefs(s *LSym) {
-	w.writeRef(s, false)
-	w.writeRef(s.Gotype, false)
-	for _, r := range s.R {
-		w.writeRef(r.Sym, false)
-	}
-
-	if s.Type == objabi.STEXT {
-		pc := &s.Func.Pcln
-		for _, d := range pc.Funcdata {
-			w.writeRef(d, false)
-		}
-		for _, f := range pc.File {
-			fsym := w.ctxt.Lookup(f)
-			w.writeRef(fsym, true)
-		}
-		for _, call := range pc.InlTree.nodes {
-			w.writeRef(call.Func, false)
-			f, _ := linkgetlineFromPos(w.ctxt, call.Pos)
-			fsym := w.ctxt.Lookup(f)
-			w.writeRef(fsym, true)
-		}
-	}
-}
-
 func (ctxt *Link) writeSymDebug(s *LSym) {
 	ctxt.writeSymDebugNamed(s, s.Name)
 }
@@ -311,138 +95,6 @@
 	}
 }
 
-func (w *objWriter) writeSym(s *LSym) {
-	ctxt := w.ctxt
-	if ctxt.Debugasm > 0 {
-		w.ctxt.writeSymDebug(s)
-	}
-
-	w.wr.WriteByte(symPrefix)
-	w.wr.WriteByte(byte(s.Type))
-	w.writeRefIndex(s)
-	flags := int64(0)
-	if s.DuplicateOK() {
-		flags |= 1
-	}
-	if s.Local() {
-		flags |= 1 << 1
-	}
-	if s.MakeTypelink() {
-		flags |= 1 << 2
-	}
-	w.writeInt(flags)
-	w.writeInt(s.Size)
-	w.writeRefIndex(s.Gotype)
-	w.writeInt(int64(len(s.P)))
-
-	w.writeInt(int64(len(s.R)))
-	var r *Reloc
-	for i := range s.R {
-		r = &s.R[i]
-		w.writeInt(int64(r.Off))
-		w.writeInt(int64(r.Siz))
-		w.writeInt(int64(r.Type))
-		w.writeInt(r.Add)
-		w.writeRefIndex(r.Sym)
-	}
-
-	if s.Type != objabi.STEXT {
-		return
-	}
-
-	w.writeInt(int64(s.Func.Args))
-	w.writeInt(int64(s.Func.Locals))
-	w.writeInt(int64(s.Func.Align))
-	w.writeBool(s.NoSplit())
-	flags = int64(0)
-	if s.Leaf() {
-		flags |= 1
-	}
-	if s.CFunc() {
-		flags |= 1 << 1
-	}
-	if s.ReflectMethod() {
-		flags |= 1 << 2
-	}
-	if ctxt.Flag_shared {
-		flags |= 1 << 3
-	}
-	if s.TopFrame() {
-		flags |= 1 << 4
-	}
-	w.writeInt(flags)
-	w.writeInt(int64(0)) // TODO: remove at next object file rev
-
-	pc := &s.Func.Pcln
-	w.writeInt(int64(len(pc.Pcsp.P)))
-	w.writeInt(int64(len(pc.Pcfile.P)))
-	w.writeInt(int64(len(pc.Pcline.P)))
-	w.writeInt(int64(len(pc.Pcinline.P)))
-	w.writeInt(int64(len(pc.Pcdata)))
-	for _, pcd := range pc.Pcdata {
-		w.writeInt(int64(len(pcd.P)))
-	}
-	w.writeInt(int64(len(pc.Funcdataoff)))
-	for i := range pc.Funcdataoff {
-		w.writeRefIndex(pc.Funcdata[i])
-	}
-	for i := range pc.Funcdataoff {
-		w.writeInt(pc.Funcdataoff[i])
-	}
-	w.writeInt(int64(len(pc.File)))
-	for _, f := range pc.File {
-		fsym := ctxt.Lookup(f)
-		w.writeRefIndex(fsym)
-	}
-	w.writeInt(int64(len(pc.InlTree.nodes)))
-	for _, call := range pc.InlTree.nodes {
-		w.writeInt(int64(call.Parent))
-		f, l := linkgetlineFromPos(w.ctxt, call.Pos)
-		fsym := ctxt.Lookup(f)
-		w.writeRefIndex(fsym)
-		w.writeInt(int64(l))
-		w.writeRefIndex(call.Func)
-		w.writeInt(int64(call.ParentPC))
-	}
-}
-
-func (w *objWriter) writeBool(b bool) {
-	if b {
-		w.writeInt(1)
-	} else {
-		w.writeInt(0)
-	}
-}
-
-func (w *objWriter) writeInt(sval int64) {
-	var v uint64
-	uv := (uint64(sval) << 1) ^ uint64(sval>>63)
-	p := w.varintbuf[:]
-	for v = uv; v >= 0x80; v >>= 7 {
-		p[0] = uint8(v | 0x80)
-		p = p[1:]
-	}
-	p[0] = uint8(v)
-	p = p[1:]
-	w.wr.Write(w.varintbuf[:len(w.varintbuf)-len(p)])
-}
-
-func (w *objWriter) writeString(s string) {
-	w.writeInt(int64(len(s)))
-	w.wr.WriteString(s)
-}
-
-func (w *objWriter) writeRefIndex(s *LSym) {
-	if s == nil {
-		w.writeInt(0)
-		return
-	}
-	if s.RefIdx == 0 {
-		log.Fatalln("writing an unreferenced symbol", s.Name)
-	}
-	w.writeInt(int64(s.RefIdx))
-}
-
 // relocByOff sorts relocations by their offsets.
 type relocByOff []Reloc
 
@@ -510,17 +162,11 @@
 func (c dwCtxt) AddFileRef(s dwarf.Sym, f interface{}) {
 	ls := s.(*LSym)
 	rsym := f.(*LSym)
-	if c.Link.Flag_go115newobj {
-		fidx := c.Link.PosTable.FileIndex(rsym.Name)
-		// Note the +1 here -- the value we're writing is going to be an
-		// index into the DWARF line table file section, whose entries
-		// are numbered starting at 1, not 0.
-		ls.WriteInt(c.Link, ls.Size, 4, int64(fidx+1))
-	} else {
-		ls.WriteAddr(c.Link, ls.Size, 4, rsym, 0)
-		r := &ls.R[len(ls.R)-1]
-		r.Type = objabi.R_DWARFFILEREF
-	}
+	fidx := c.Link.PosTable.FileIndex(rsym.Name)
+	// Note the +1 here -- the value we're writing is going to be an
+	// index into the DWARF line table file section, whose entries
+	// are numbered starting at 1, not 0.
+	ls.WriteInt(c.Link, ls.Size, 4, int64(fidx+1))
 }
 
 func (c dwCtxt) CurrentOffset(s dwarf.Sym) int64 {
@@ -558,28 +204,19 @@
 		ctxt.Diag("dwarfSym of non-TEXT %v", s)
 	}
 	if s.Func.dwarfInfoSym == nil {
-		if ctxt.Flag_go115newobj {
-			s.Func.dwarfInfoSym = &LSym{
-				Type: objabi.SDWARFINFO,
+		s.Func.dwarfInfoSym = &LSym{
+			Type: objabi.SDWARFINFO,
+		}
+		if ctxt.Flag_locationlists {
+			s.Func.dwarfLocSym = &LSym{
+				Type: objabi.SDWARFLOC,
 			}
-			if ctxt.Flag_locationlists {
-				s.Func.dwarfLocSym = &LSym{
-					Type: objabi.SDWARFLOC,
-				}
-			}
-			s.Func.dwarfRangesSym = &LSym{
-				Type: objabi.SDWARFRANGE,
-			}
-			s.Func.dwarfDebugLinesSym = &LSym{
-				Type: objabi.SDWARFLINES,
-			}
-		} else {
-			s.Func.dwarfInfoSym = ctxt.LookupDerived(s, dwarf.InfoPrefix+s.Name)
-			if ctxt.Flag_locationlists {
-				s.Func.dwarfLocSym = ctxt.LookupDerived(s, dwarf.LocPrefix+s.Name)
-			}
-			s.Func.dwarfRangesSym = ctxt.LookupDerived(s, dwarf.RangePrefix+s.Name)
-			s.Func.dwarfDebugLinesSym = ctxt.LookupDerived(s, dwarf.DebugLinesPrefix+s.Name)
+		}
+		s.Func.dwarfRangesSym = &LSym{
+			Type: objabi.SDWARFRANGE,
+		}
+		s.Func.dwarfDebugLinesSym = &LSym{
+			Type: objabi.SDWARFLINES,
 		}
 		if s.WasInlined() {
 			s.Func.dwarfAbsFnSym = ctxt.DwFixups.AbsFuncDwarfSym(s)
diff --git a/src/cmd/internal/obj/objfile2.go b/src/cmd/internal/obj/objfile2.go
index 061e43c..0b3b2be 100644
--- a/src/cmd/internal/obj/objfile2.go
+++ b/src/cmd/internal/obj/objfile2.go
@@ -17,7 +17,7 @@
 )
 
 // Entry point of writing new object file.
-func WriteObjFile2(ctxt *Link, b *bio.Writer, pkgpath string) {
+func WriteObjFile(ctxt *Link, b *bio.Writer, pkgpath string) {
 
 	debugAsmEmit(ctxt)
 
diff --git a/src/cmd/internal/obj/plist.go b/src/cmd/internal/obj/plist.go
index 44ec460..c82257c 100644
--- a/src/cmd/internal/obj/plist.go
+++ b/src/cmd/internal/obj/plist.go
@@ -139,26 +139,7 @@
 	ctxt.Text = append(ctxt.Text, s)
 
 	// Set up DWARF entries for s
-	info, loc, ranges, _, lines := ctxt.dwarfSym(s)
-
-	// When using new object files, the DWARF symbols are unnamed aux
-	// symbols and don't need to be added to ctxt.Data.
-	// But the old object file still needs them.
-	if !ctxt.Flag_go115newobj {
-		info.Type = objabi.SDWARFINFO
-		info.Set(AttrDuplicateOK, s.DuplicateOK())
-		if loc != nil {
-			loc.Type = objabi.SDWARFLOC
-			loc.Set(AttrDuplicateOK, s.DuplicateOK())
-			ctxt.Data = append(ctxt.Data, loc)
-		}
-		ranges.Type = objabi.SDWARFRANGE
-		ranges.Set(AttrDuplicateOK, s.DuplicateOK())
-		ctxt.Data = append(ctxt.Data, info, ranges)
-		lines.Type = objabi.SDWARFLINES
-		lines.Set(AttrDuplicateOK, s.DuplicateOK())
-		ctxt.Data = append(ctxt.Data, lines)
-	}
+	ctxt.dwarfSym(s)
 }
 
 func (ctxt *Link) Globl(s *LSym, size int64, flag int) {
diff --git a/src/cmd/internal/obj/sym.go b/src/cmd/internal/obj/sym.go
index 4a8b0eb..61ef6ff 100644
--- a/src/cmd/internal/obj/sym.go
+++ b/src/cmd/internal/obj/sym.go
@@ -165,10 +165,6 @@
 // asm is set to true if this is called by the assembler (i.e. not the compiler),
 // in which case all the symbols are non-package (for now).
 func (ctxt *Link) NumberSyms(asm bool) {
-	if !ctxt.Flag_go115newobj {
-		return
-	}
-
 	if ctxt.Headtype == objabi.Haix {
 		// Data must be sorted to keep a constant order in TOC symbols.
 		// As they are created during Progedit, two symbols can be switched between
diff --git a/src/cmd/link/internal/ld/main.go b/src/cmd/link/internal/ld/main.go
index 1ed8ccb..b95bab3 100644
--- a/src/cmd/link/internal/ld/main.go
+++ b/src/cmd/link/internal/ld/main.go
@@ -39,7 +39,6 @@
 	"flag"
 	"log"
 	"os"
-	"os/exec"
 	"runtime"
 	"runtime/pprof"
 	"strings"
@@ -99,8 +98,6 @@
 
 	benchmarkFlag     = flag.String("benchmark", "", "set to 'mem' or 'cpu' to enable phase benchmarking")
 	benchmarkFileFlag = flag.String("benchmarkprofile", "", "emit phase profiles to `base`_phase.{cpu,mem}prof")
-
-	flagGo115Newobj = flag.Bool("go115newobj", true, "use new object file format")
 )
 
 // Main is the main entry point for the linker code.
@@ -140,10 +137,6 @@
 
 	objabi.Flagparse(usage)
 
-	if !*flagGo115Newobj {
-		oldlink()
-	}
-
 	switch *flagHeadType {
 	case "":
 	case "windowsgui":
@@ -415,48 +408,3 @@
 		})
 	}
 }
-
-// Invoke the old linker and exit.
-func oldlink() {
-	linker := os.Args[0]
-	if strings.HasSuffix(linker, "link") {
-		linker = linker[:len(linker)-4] + "oldlink"
-	} else if strings.HasSuffix(linker, "link.exe") {
-		linker = linker[:len(linker)-8] + "oldlink.exe"
-	} else {
-		log.Fatal("cannot find oldlink. arg0=", linker)
-	}
-
-	// Copy args, filter out -go115newobj flag
-	args := make([]string, 0, len(os.Args)-1)
-	skipNext := false
-	for i, a := range os.Args {
-		if i == 0 {
-			continue // skip arg0
-		}
-		if skipNext {
-			skipNext = false
-			continue
-		}
-		if a == "-go115newobj" {
-			skipNext = true
-			continue
-		}
-		if strings.HasPrefix(a, "-go115newobj=") {
-			continue
-		}
-		args = append(args, a)
-	}
-
-	cmd := exec.Command(linker, args...)
-	cmd.Stdout = os.Stdout
-	cmd.Stderr = os.Stderr
-	err := cmd.Run()
-	if err == nil {
-		os.Exit(0)
-	}
-	if _, ok := err.(*exec.ExitError); ok {
-		os.Exit(2) // would be nice to use ExitError.ExitCode(), but that is too new
-	}
-	log.Fatal("invoke oldlink failed:", err)
-}
diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go
index 1b62d05..02cd0b8 100644
--- a/src/cmd/link/internal/loader/loader.go
+++ b/src/cmd/link/internal/loader/loader.go
@@ -1914,7 +1914,7 @@
 	r := goobj2.NewReaderFromBytes(roObject, readonly)
 	if r == nil {
 		if len(roObject) >= 8 && bytes.Equal(roObject[:8], []byte("\x00go114ld")) {
-			log.Fatalf("found object file %s in old format, but -go115newobj is true\nset -go115newobj consistently in all -gcflags, -asmflags, and -ldflags", f.File().Name())
+			log.Fatalf("found object file %s in old format", f.File().Name())
 		}
 		panic("cannot read object file")
 	}
diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go
index 1c9e177..145eb3c 100644
--- a/src/cmd/link/link_test.go
+++ b/src/cmd/link/link_test.go
@@ -535,30 +535,6 @@
 	}
 }
 
-func TestOldLink(t *testing.T) {
-	// Test that old object file format still works.
-	// TODO(go115newobj): delete.
-
-	testenv.MustHaveGoBuild(t)
-
-	tmpdir, err := ioutil.TempDir("", "TestOldLink")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
-
-	src := filepath.Join(tmpdir, "main.go")
-	err = ioutil.WriteFile(src, []byte("package main; func main(){}\n"), 0666)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	cmd := exec.Command(testenv.GoToolPath(t), "run", "-gcflags=all=-go115newobj=false", "-asmflags=all=-go115newobj=false", "-ldflags=-go115newobj=false", src)
-	if out, err := cmd.CombinedOutput(); err != nil {
-		t.Errorf("%v: %v:\n%s", cmd.Args, err, out)
-	}
-}
-
 const testFuncAlignSrc = `
 package main
 import (
diff --git a/src/cmd/nm/nm_test.go b/src/cmd/nm/nm_test.go
index a49423b..cdffb68 100644
--- a/src/cmd/nm/nm_test.go
+++ b/src/cmd/nm/nm_test.go
@@ -335,11 +335,11 @@
 }
 
 // Check that a symbol has a given name, accepting both
-// new and old objects.
-// TODO(go115newobj): remove.
+// with (for packaged symbols) and without index (for
+// non-package symbols).
 func matchSymName(symname, want string) bool {
 	return symname == want ||
-		strings.HasPrefix(symname, want+"#") // new style, with index
+		strings.HasPrefix(symname, want+"#")
 }
 
 const testexec = `
diff --git a/src/cmd/objdump/objdump_test.go b/src/cmd/objdump/objdump_test.go
index 814cbf4..be271e4 100644
--- a/src/cmd/objdump/objdump_test.go
+++ b/src/cmd/objdump/objdump_test.go
@@ -286,9 +286,8 @@
 		t.Fatalf("go tool compile fmthello.go: %v\n%s", err, out)
 	}
 
-	// TODO(go115newobj): drop old object file support.
 	need := []string{
-		`main(#\d+)?\(SB\)`, // either new or old object file
+		`main#\d+\(SB\)`,
 		`fmthello\.go:6`,
 	}
 
diff --git a/src/cmd/oldlink/doc.go b/src/cmd/oldlink/doc.go
deleted file mode 100644
index 219499b..0000000
--- a/src/cmd/oldlink/doc.go
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-Link, typically invoked as ``go tool link,'' reads the Go archive or object
-for a package main, along with its dependencies, and combines them
-into an executable binary.
-
-Command Line
-
-Usage:
-
-	go tool link [flags] main.a
-
-Flags:
-
-	-B note
-		Add an ELF_NT_GNU_BUILD_ID note when using ELF.
-		The value should start with 0x and be an even number of hex digits.
-	-D address
-		Set data segment address.
-	-E entry
-		Set entry symbol name.
-	-H type
-		Set executable format type.
-		The default format is inferred from GOOS and GOARCH.
-		On Windows, -H windowsgui writes a "GUI binary" instead of a "console binary."
-	-I interpreter
-		Set the ELF dynamic linker to use.
-	-L dir1 -L dir2
-		Search for imported packages in dir1, dir2, etc,
-		after consulting $GOROOT/pkg/$GOOS_$GOARCH.
-	-R quantum
-		Set address rounding quantum.
-	-T address
-		Set text segment address.
-	-V
-		Print linker version and exit.
-	-X importpath.name=value
-		Set the value of the string variable in importpath named name to value.
-		This is only effective if the variable is declared in the source code either uninitialized
-		or initialized to a constant string expression. -X will not work if the initializer makes
-		a function call or refers to other variables.
-		Note that before Go 1.5 this option took two separate arguments.
-	-a
-		Disassemble output.
-	-buildid id
-		Record id as Go toolchain build id.
-	-buildmode mode
-		Set build mode (default exe).
-	-c
-		Dump call graphs.
-	-compressdwarf
-		Compress DWARF if possible (default true).
-	-cpuprofile file
-		Write CPU profile to file.
-	-d
-		Disable generation of dynamic executables.
-		The emitted code is the same in either case; the option
-		controls only whether a dynamic header is included.
-		The dynamic header is on by default, even without any
-		references to dynamic libraries, because many common
-		system tools now assume the presence of the header.
-	-debugtramp int
-		Debug trampolines.
-	-dumpdep
-		Dump symbol dependency graph.
-	-extar ar
-		Set the external archive program (default "ar").
-		Used only for -buildmode=c-archive.
-	-extld linker
-		Set the external linker (default "clang" or "gcc").
-	-extldflags flags
-		Set space-separated flags to pass to the external linker.
-	-f
-		Ignore version mismatch in the linked archives.
-	-g
-		Disable Go package data checks.
-	-importcfg file
-		Read import configuration from file.
-		In the file, set packagefile, packageshlib to specify import resolution.
-	-installsuffix suffix
-		Look for packages in $GOROOT/pkg/$GOOS_$GOARCH_suffix
-		instead of $GOROOT/pkg/$GOOS_$GOARCH.
-	-k symbol
-		Set field tracking symbol. Use this flag when GOEXPERIMENT=fieldtrack is set.
-	-libgcc file
-		Set name of compiler support library.
-		This is only used in internal link mode.
-		If not set, default value comes from running the compiler,
-		which may be set by the -extld option.
-		Set to "none" to use no support library.
-	-linkmode mode
-		Set link mode (internal, external, auto).
-		This sets the linking mode as described in cmd/cgo/doc.go.
-	-linkshared
-		Link against installed Go shared libraries (experimental).
-	-memprofile file
-		Write memory profile to file.
-	-memprofilerate rate
-		Set runtime.MemProfileRate to rate.
-	-msan
-		Link with C/C++ memory sanitizer support.
-	-n
-		Dump symbol table.
-	-o file
-		Write output to file (default a.out, or a.out.exe on Windows).
-	-pluginpath path
-		The path name used to prefix exported plugin symbols.
-	-r dir1:dir2:...
-		Set the ELF dynamic linker search path.
-	-race
-		Link with race detection libraries.
-	-s
-		Omit the symbol table and debug information.
-	-shared
-		Generated shared object (implies -linkmode external; experimental).
-	-tmpdir dir
-		Write temporary files to dir.
-		Temporary files are only used in external linking mode.
-	-u
-		Reject unsafe packages.
-	-v
-		Print trace of linker operations.
-	-w
-		Omit the DWARF symbol table.
-*/
-package main
diff --git a/src/cmd/oldlink/internal/amd64/asm.go b/src/cmd/oldlink/internal/amd64/asm.go
deleted file mode 100644
index c120e4e..0000000
--- a/src/cmd/oldlink/internal/amd64/asm.go
+++ /dev/null
@@ -1,874 +0,0 @@
-// Inferno utils/6l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/asm.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package amd64
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-	"cmd/oldlink/internal/sym"
-	"debug/elf"
-	"log"
-)
-
-func PADDR(x uint32) uint32 {
-	return x &^ 0x80000000
-}
-
-func Addcall(ctxt *ld.Link, s *sym.Symbol, t *sym.Symbol) int64 {
-	s.Attr |= sym.AttrReachable
-	i := s.Size
-	s.Size += 4
-	s.Grow(s.Size)
-	r := s.AddRel()
-	r.Sym = t
-	r.Off = int32(i)
-	r.Type = objabi.R_CALL
-	r.Siz = 4
-	return i + int64(r.Siz)
-}
-
-func gentext(ctxt *ld.Link) {
-	if !ctxt.DynlinkingGo() {
-		return
-	}
-	addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-	if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
-		// we're linking a module containing the runtime -> no need for
-		// an init function
-		return
-	}
-	addmoduledata.Attr |= sym.AttrReachable
-	initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-	initfunc.Type = sym.STEXT
-	initfunc.Attr |= sym.AttrLocal
-	initfunc.Attr |= sym.AttrReachable
-	o := func(op ...uint8) {
-		for _, op1 := range op {
-			initfunc.AddUint8(op1)
-		}
-	}
-	// 0000000000000000 <local.dso_init>:
-	//    0:	48 8d 3d 00 00 00 00 	lea    0x0(%rip),%rdi        # 7 <local.dso_init+0x7>
-	// 			3: R_X86_64_PC32	runtime.firstmoduledata-0x4
-	o(0x48, 0x8d, 0x3d)
-	initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata, 0)
-	//    7:	e8 00 00 00 00       	callq  c <local.dso_init+0xc>
-	// 			8: R_X86_64_PLT32	runtime.addmoduledata-0x4
-	o(0xe8)
-	Addcall(ctxt, initfunc, addmoduledata)
-	//    c:	c3                   	retq
-	o(0xc3)
-	if ctxt.BuildMode == ld.BuildModePlugin {
-		ctxt.Textp = append(ctxt.Textp, addmoduledata)
-	}
-	ctxt.Textp = append(ctxt.Textp, initfunc)
-	initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-	initarray_entry.Attr |= sym.AttrReachable
-	initarray_entry.Attr |= sym.AttrLocal
-	initarray_entry.Type = sym.SINITARR
-	initarray_entry.AddAddr(ctxt.Arch, initfunc)
-}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-	targ := r.Sym
-
-	switch r.Type {
-	default:
-		if r.Type >= objabi.ElfRelocOffset {
-			ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
-			return false
-		}
-
-		// Handle relocations found in ELF object files.
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_PC32):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected R_X86_64_PC32 relocation for dynamic symbol %s", targ.Name)
-		}
-		// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
-		// sense and should be removed when someone has thought about it properly.
-		if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
-			ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
-		}
-		r.Type = objabi.R_PCREL
-		r.Add += 4
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_PC64):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected R_X86_64_PC64 relocation for dynamic symbol %s", targ.Name)
-		}
-		if targ.Type == 0 || targ.Type == sym.SXREF {
-			ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
-		}
-		r.Type = objabi.R_PCREL
-		r.Add += 8
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_PLT32):
-		r.Type = objabi.R_PCREL
-		r.Add += 4
-		if targ.Type == sym.SDYNIMPORT {
-			addpltsym(ctxt, targ)
-			r.Sym = ctxt.Syms.Lookup(".plt", 0)
-			r.Add += int64(targ.Plt())
-		}
-
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_GOTPCREL),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_GOTPCRELX),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_REX_GOTPCRELX):
-		if targ.Type != sym.SDYNIMPORT {
-			// have symbol
-			if r.Off >= 2 && s.P[r.Off-2] == 0x8b {
-				// turn MOVQ of GOT entry into LEAQ of symbol itself
-				s.P[r.Off-2] = 0x8d
-
-				r.Type = objabi.R_PCREL
-				r.Add += 4
-				return true
-			}
-		}
-
-		// fall back to using GOT and hope for the best (CMOV*)
-		// TODO: just needs relocation, no need to put in .dynsym
-		addgotsym(ctxt, targ)
-
-		r.Type = objabi.R_PCREL
-		r.Sym = ctxt.Syms.Lookup(".got", 0)
-		r.Add += 4
-		r.Add += int64(targ.Got())
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_64):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected R_X86_64_64 relocation for dynamic symbol %s", targ.Name)
-		}
-		r.Type = objabi.R_ADDR
-		if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal {
-			// For internal linking PIE, this R_ADDR relocation cannot
-			// be resolved statically. We need to generate a dynamic
-			// relocation. Let the code below handle it.
-			break
-		}
-		return true
-
-	// Handle relocations found in Mach-O object files.
-	case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_UNSIGNED*2 + 0,
-		objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED*2 + 0,
-		objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_BRANCH*2 + 0:
-		// TODO: What is the difference between all these?
-		r.Type = objabi.R_ADDR
-
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected reloc for dynamic symbol %s", targ.Name)
-		}
-		return true
-
-	case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_BRANCH*2 + 1:
-		if targ.Type == sym.SDYNIMPORT {
-			addpltsym(ctxt, targ)
-			r.Sym = ctxt.Syms.Lookup(".plt", 0)
-			r.Add = int64(targ.Plt())
-			r.Type = objabi.R_PCREL
-			return true
-		}
-		fallthrough
-
-	case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_UNSIGNED*2 + 1,
-		objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED*2 + 1,
-		objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED_1*2 + 1,
-		objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED_2*2 + 1,
-		objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED_4*2 + 1:
-		r.Type = objabi.R_PCREL
-
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected pc-relative reloc for dynamic symbol %s", targ.Name)
-		}
-		return true
-
-	case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_GOT_LOAD*2 + 1:
-		if targ.Type != sym.SDYNIMPORT {
-			// have symbol
-			// turn MOVQ of GOT entry into LEAQ of symbol itself
-			if r.Off < 2 || s.P[r.Off-2] != 0x8b {
-				ld.Errorf(s, "unexpected GOT_LOAD reloc for non-dynamic symbol %s", targ.Name)
-				return false
-			}
-
-			s.P[r.Off-2] = 0x8d
-			r.Type = objabi.R_PCREL
-			return true
-		}
-		fallthrough
-
-	case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_GOT*2 + 1:
-		if targ.Type != sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
-		}
-		addgotsym(ctxt, targ)
-		r.Type = objabi.R_PCREL
-		r.Sym = ctxt.Syms.Lookup(".got", 0)
-		r.Add += int64(targ.Got())
-		return true
-	}
-
-	switch r.Type {
-	case objabi.R_CALL,
-		objabi.R_PCREL:
-		if targ.Type != sym.SDYNIMPORT {
-			// nothing to do, the relocation will be laid out in reloc
-			return true
-		}
-		if ctxt.LinkMode == ld.LinkExternal {
-			// External linker will do this relocation.
-			return true
-		}
-		// Internal linking, for both ELF and Mach-O.
-		// Build a PLT entry and change the relocation target to that entry.
-		addpltsym(ctxt, targ)
-		r.Sym = ctxt.Syms.Lookup(".plt", 0)
-		r.Add = int64(targ.Plt())
-		return true
-
-	case objabi.R_ADDR:
-		if s.Type == sym.STEXT && ctxt.IsELF {
-			if ctxt.HeadType == objabi.Hsolaris {
-				addpltsym(ctxt, targ)
-				r.Sym = ctxt.Syms.Lookup(".plt", 0)
-				r.Add += int64(targ.Plt())
-				return true
-			}
-			// The code is asking for the address of an external
-			// function. We provide it with the address of the
-			// correspondent GOT symbol.
-			addgotsym(ctxt, targ)
-
-			r.Sym = ctxt.Syms.Lookup(".got", 0)
-			r.Add += int64(targ.Got())
-			return true
-		}
-
-		// Process dynamic relocations for the data sections.
-		if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal {
-			// When internally linking, generate dynamic relocations
-			// for all typical R_ADDR relocations. The exception
-			// are those R_ADDR that are created as part of generating
-			// the dynamic relocations and must be resolved statically.
-			//
-			// There are three phases relevant to understanding this:
-			//
-			//	dodata()  // we are here
-			//	address() // symbol address assignment
-			//	reloc()   // resolution of static R_ADDR relocs
-			//
-			// At this point symbol addresses have not been
-			// assigned yet (as the final size of the .rela section
-			// will affect the addresses), and so we cannot write
-			// the Elf64_Rela.r_offset now. Instead we delay it
-			// until after the 'address' phase of the linker is
-			// complete. We do this via Addaddrplus, which creates
-			// a new R_ADDR relocation which will be resolved in
-			// the 'reloc' phase.
-			//
-			// These synthetic static R_ADDR relocs must be skipped
-			// now, or else we will be caught in an infinite loop
-			// of generating synthetic relocs for our synthetic
-			// relocs.
-			//
-			// Furthermore, the rela sections contain dynamic
-			// relocations with R_ADDR relocations on
-			// Elf64_Rela.r_offset. This field should contain the
-			// symbol offset as determined by reloc(), not the
-			// final dynamically linked address as a dynamic
-			// relocation would provide.
-			switch s.Name {
-			case ".dynsym", ".rela", ".rela.plt", ".got.plt", ".dynamic":
-				return false
-			}
-		} else {
-			// Either internally linking a static executable,
-			// in which case we can resolve these relocations
-			// statically in the 'reloc' phase, or externally
-			// linking, in which case the relocation will be
-			// prepared in the 'reloc' phase and passed to the
-			// external linker in the 'asmb' phase.
-			if s.Type != sym.SDATA && s.Type != sym.SRODATA {
-				break
-			}
-		}
-
-		if ctxt.IsELF {
-			// Generate R_X86_64_RELATIVE relocations for best
-			// efficiency in the dynamic linker.
-			//
-			// As noted above, symbol addresses have not been
-			// assigned yet, so we can't generate the final reloc
-			// entry yet. We ultimately want:
-			//
-			// r_offset = s + r.Off
-			// r_info = R_X86_64_RELATIVE
-			// r_addend = targ + r.Add
-			//
-			// The dynamic linker will set *offset = base address +
-			// addend.
-			//
-			// AddAddrPlus is used for r_offset and r_addend to
-			// generate new R_ADDR relocations that will update
-			// these fields in the 'reloc' phase.
-			rela := ctxt.Syms.Lookup(".rela", 0)
-			rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
-			if r.Siz == 8 {
-				rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_X86_64_RELATIVE)))
-			} else {
-				ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
-			}
-			rela.AddAddrPlus(ctxt.Arch, targ, int64(r.Add))
-			// Not mark r done here. So we still apply it statically,
-			// so in the file content we'll also have the right offset
-			// to the relocation target. So it can be examined statically
-			// (e.g. go version).
-			return true
-		}
-
-		if ctxt.HeadType == objabi.Hdarwin && s.Size == int64(ctxt.Arch.PtrSize) && r.Off == 0 {
-			// Mach-O relocations are a royal pain to lay out.
-			// They use a compact stateful bytecode representation
-			// that is too much bother to deal with.
-			// Instead, interpret the C declaration
-			//	void *_Cvar_stderr = &stderr;
-			// as making _Cvar_stderr the name of a GOT entry
-			// for stderr. This is separate from the usual GOT entry,
-			// just in case the C code assigns to the variable,
-			// and of course it only works for single pointers,
-			// but we only need to support cgo and that's all it needs.
-			ld.Adddynsym(ctxt, targ)
-
-			got := ctxt.Syms.Lookup(".got", 0)
-			s.Type = got.Type
-			s.Attr |= sym.AttrSubSymbol
-			s.Outer = got
-			s.Sub = got.Sub
-			got.Sub = s
-			s.Value = got.Size
-			got.AddUint64(ctxt.Arch, 0)
-			ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(targ.Dynid))
-			r.Type = objabi.ElfRelocOffset // ignore during relocsym
-			return true
-		}
-	}
-
-	return false
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-	ctxt.Out.Write64(uint64(sectoff))
-
-	elfsym := r.Xsym.ElfsymForReloc()
-	switch r.Type {
-	default:
-		return false
-	case objabi.R_ADDR:
-		if r.Siz == 4 {
-			ctxt.Out.Write64(uint64(elf.R_X86_64_32) | uint64(elfsym)<<32)
-		} else if r.Siz == 8 {
-			ctxt.Out.Write64(uint64(elf.R_X86_64_64) | uint64(elfsym)<<32)
-		} else {
-			return false
-		}
-	case objabi.R_TLS_LE:
-		if r.Siz == 4 {
-			ctxt.Out.Write64(uint64(elf.R_X86_64_TPOFF32) | uint64(elfsym)<<32)
-		} else {
-			return false
-		}
-	case objabi.R_TLS_IE:
-		if r.Siz == 4 {
-			ctxt.Out.Write64(uint64(elf.R_X86_64_GOTTPOFF) | uint64(elfsym)<<32)
-		} else {
-			return false
-		}
-	case objabi.R_CALL:
-		if r.Siz == 4 {
-			if r.Xsym.Type == sym.SDYNIMPORT {
-				if ctxt.DynlinkingGo() {
-					ctxt.Out.Write64(uint64(elf.R_X86_64_PLT32) | uint64(elfsym)<<32)
-				} else {
-					ctxt.Out.Write64(uint64(elf.R_X86_64_GOTPCREL) | uint64(elfsym)<<32)
-				}
-			} else {
-				ctxt.Out.Write64(uint64(elf.R_X86_64_PC32) | uint64(elfsym)<<32)
-			}
-		} else {
-			return false
-		}
-	case objabi.R_PCREL:
-		if r.Siz == 4 {
-			if r.Xsym.Type == sym.SDYNIMPORT && r.Xsym.ElfType() == elf.STT_FUNC {
-				ctxt.Out.Write64(uint64(elf.R_X86_64_PLT32) | uint64(elfsym)<<32)
-			} else {
-				ctxt.Out.Write64(uint64(elf.R_X86_64_PC32) | uint64(elfsym)<<32)
-			}
-		} else {
-			return false
-		}
-	case objabi.R_GOTPCREL:
-		if r.Siz == 4 {
-			ctxt.Out.Write64(uint64(elf.R_X86_64_GOTPCREL) | uint64(elfsym)<<32)
-		} else {
-			return false
-		}
-	}
-
-	ctxt.Out.Write64(uint64(r.Xadd))
-	return true
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-	var v uint32
-
-	rs := r.Xsym
-
-	if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_PCREL || r.Type == objabi.R_GOTPCREL || r.Type == objabi.R_CALL {
-		if rs.Dynid < 0 {
-			ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
-			return false
-		}
-
-		v = uint32(rs.Dynid)
-		v |= 1 << 27 // external relocation
-	} else {
-		v = uint32(rs.Sect.Extnum)
-		if v == 0 {
-			ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
-			return false
-		}
-	}
-
-	switch r.Type {
-	default:
-		return false
-
-	case objabi.R_ADDR:
-		v |= ld.MACHO_X86_64_RELOC_UNSIGNED << 28
-
-	case objabi.R_CALL:
-		v |= 1 << 24 // pc-relative bit
-		v |= ld.MACHO_X86_64_RELOC_BRANCH << 28
-
-		// NOTE: Only works with 'external' relocation. Forced above.
-	case objabi.R_PCREL:
-		v |= 1 << 24 // pc-relative bit
-		v |= ld.MACHO_X86_64_RELOC_SIGNED << 28
-	case objabi.R_GOTPCREL:
-		v |= 1 << 24 // pc-relative bit
-		v |= ld.MACHO_X86_64_RELOC_GOT_LOAD << 28
-	}
-
-	switch r.Siz {
-	default:
-		return false
-
-	case 1:
-		v |= 0 << 25
-
-	case 2:
-		v |= 1 << 25
-
-	case 4:
-		v |= 2 << 25
-
-	case 8:
-		v |= 3 << 25
-	}
-
-	out.Write32(uint32(sectoff))
-	out.Write32(v)
-	return true
-}
-
-func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-	var v uint32
-
-	rs := r.Xsym
-
-	if rs.Dynid < 0 {
-		ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
-		return false
-	}
-
-	out.Write32(uint32(sectoff))
-	out.Write32(uint32(rs.Dynid))
-
-	switch r.Type {
-	default:
-		return false
-
-	case objabi.R_DWARFSECREF:
-		v = ld.IMAGE_REL_AMD64_SECREL
-
-	case objabi.R_ADDR:
-		if r.Siz == 8 {
-			v = ld.IMAGE_REL_AMD64_ADDR64
-		} else {
-			v = ld.IMAGE_REL_AMD64_ADDR32
-		}
-
-	case objabi.R_CALL,
-		objabi.R_PCREL:
-		v = ld.IMAGE_REL_AMD64_REL32
-	}
-
-	out.Write16(uint16(v))
-
-	return true
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-	return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-	log.Fatalf("unexpected relocation variant")
-	return t
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-	plt := ctxt.Syms.Lookup(".plt", 0)
-	got := ctxt.Syms.Lookup(".got.plt", 0)
-	if plt.Size == 0 {
-		// pushq got+8(IP)
-		plt.AddUint8(0xff)
-
-		plt.AddUint8(0x35)
-		plt.AddPCRelPlus(ctxt.Arch, got, 8)
-
-		// jmpq got+16(IP)
-		plt.AddUint8(0xff)
-
-		plt.AddUint8(0x25)
-		plt.AddPCRelPlus(ctxt.Arch, got, 16)
-
-		// nopl 0(AX)
-		plt.AddUint32(ctxt.Arch, 0x00401f0f)
-
-		// assume got->size == 0 too
-		got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
-
-		got.AddUint64(ctxt.Arch, 0)
-		got.AddUint64(ctxt.Arch, 0)
-	}
-}
-
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
-	if s.Plt() >= 0 {
-		return
-	}
-
-	ld.Adddynsym(ctxt, s)
-
-	if ctxt.IsELF {
-		plt := ctxt.Syms.Lookup(".plt", 0)
-		got := ctxt.Syms.Lookup(".got.plt", 0)
-		rela := ctxt.Syms.Lookup(".rela.plt", 0)
-		if plt.Size == 0 {
-			elfsetupplt(ctxt)
-		}
-
-		// jmpq *got+size(IP)
-		plt.AddUint8(0xff)
-
-		plt.AddUint8(0x25)
-		plt.AddPCRelPlus(ctxt.Arch, got, got.Size)
-
-		// add to got: pointer to current pos in plt
-		got.AddAddrPlus(ctxt.Arch, plt, plt.Size)
-
-		// pushq $x
-		plt.AddUint8(0x68)
-
-		plt.AddUint32(ctxt.Arch, uint32((got.Size-24-8)/8))
-
-		// jmpq .plt
-		plt.AddUint8(0xe9)
-
-		plt.AddUint32(ctxt.Arch, uint32(-(plt.Size + 4)))
-
-		// rela
-		rela.AddAddrPlus(ctxt.Arch, got, got.Size-8)
-
-		rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_X86_64_JMP_SLOT)))
-		rela.AddUint64(ctxt.Arch, 0)
-
-		s.SetPlt(int32(plt.Size - 16))
-	} else if ctxt.HeadType == objabi.Hdarwin {
-		// To do lazy symbol lookup right, we're supposed
-		// to tell the dynamic loader which library each
-		// symbol comes from and format the link info
-		// section just so. I'm too lazy (ha!) to do that
-		// so for now we'll just use non-lazy pointers,
-		// which don't need to be told which library to use.
-		//
-		// https://networkpx.blogspot.com/2009/09/about-lcdyldinfoonly-command.html
-		// has details about what we're avoiding.
-
-		addgotsym(ctxt, s)
-		plt := ctxt.Syms.Lookup(".plt", 0)
-
-		ctxt.Syms.Lookup(".linkedit.plt", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
-
-		// jmpq *got+size(IP)
-		s.SetPlt(int32(plt.Size))
-
-		plt.AddUint8(0xff)
-		plt.AddUint8(0x25)
-		plt.AddPCRelPlus(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got()))
-	} else {
-		ld.Errorf(s, "addpltsym: unsupported binary format")
-	}
-}
-
-func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
-	if s.Got() >= 0 {
-		return
-	}
-
-	ld.Adddynsym(ctxt, s)
-	got := ctxt.Syms.Lookup(".got", 0)
-	s.SetGot(int32(got.Size))
-	got.AddUint64(ctxt.Arch, 0)
-
-	if ctxt.IsELF {
-		rela := ctxt.Syms.Lookup(".rela", 0)
-		rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
-		rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_X86_64_GLOB_DAT)))
-		rela.AddUint64(ctxt.Arch, 0)
-	} else if ctxt.HeadType == objabi.Hdarwin {
-		ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
-	} else {
-		ld.Errorf(s, "addgotsym: unsupported binary format")
-	}
-}
-
-func asmb(ctxt *ld.Link) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	sect := ld.Segtext.Sections[0]
-	ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-	// 0xCC is INT $3 - breakpoint instruction
-	ld.CodeblkPad(ctxt, int64(sect.Vaddr), int64(sect.Length), []byte{0xCC})
-	for _, sect = range ld.Segtext.Sections[1:] {
-		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-		ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-	}
-	if ld.Segrelrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
-	}
-
-	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-	machlink := int64(0)
-	if ctxt.HeadType == objabi.Hdarwin {
-		machlink = ld.Domacholink(ctxt)
-	}
-
-	switch ctxt.HeadType {
-	default:
-		ld.Errorf(nil, "unknown header type %v", ctxt.HeadType)
-		fallthrough
-
-	case objabi.Hplan9:
-		break
-
-	case objabi.Hdarwin:
-		ld.Flag8 = true /* 64-bit addresses */
-
-	case objabi.Hlinux,
-		objabi.Hfreebsd,
-		objabi.Hnetbsd,
-		objabi.Hopenbsd,
-		objabi.Hdragonfly,
-		objabi.Hsolaris:
-		ld.Flag8 = true /* 64-bit addresses */
-
-	case objabi.Hwindows:
-		break
-	}
-
-	ld.Symsize = 0
-	ld.Spsize = 0
-	ld.Lcsize = 0
-	symo := int64(0)
-	if !*ld.FlagS {
-		switch ctxt.HeadType {
-		default:
-		case objabi.Hplan9:
-			*ld.FlagS = true
-			symo = int64(ld.Segdata.Fileoff + ld.Segdata.Filelen)
-
-		case objabi.Hdarwin:
-			symo = int64(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(*ld.FlagRound))) + uint64(machlink))
-
-		case objabi.Hlinux,
-			objabi.Hfreebsd,
-			objabi.Hnetbsd,
-			objabi.Hopenbsd,
-			objabi.Hdragonfly,
-			objabi.Hsolaris:
-			symo = int64(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-			symo = ld.Rnd(symo, int64(*ld.FlagRound))
-
-		case objabi.Hwindows:
-			symo = int64(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-			symo = ld.Rnd(symo, ld.PEFILEALIGN)
-		}
-
-		ctxt.Out.SeekSet(symo)
-		switch ctxt.HeadType {
-		default:
-			if ctxt.IsELF {
-				ctxt.Out.SeekSet(symo)
-				ld.Asmelfsym(ctxt)
-				ctxt.Out.Flush()
-				ctxt.Out.Write(ld.Elfstrdat)
-
-				if ctxt.LinkMode == ld.LinkExternal {
-					ld.Elfemitreloc(ctxt)
-				}
-			}
-
-		case objabi.Hplan9:
-			ld.Asmplan9sym(ctxt)
-			ctxt.Out.Flush()
-
-			sym := ctxt.Syms.Lookup("pclntab", 0)
-			if sym != nil {
-				ld.Lcsize = int32(len(sym.P))
-				ctxt.Out.Write(sym.P)
-				ctxt.Out.Flush()
-			}
-
-		case objabi.Hwindows:
-			// Do nothing
-
-		case objabi.Hdarwin:
-			if ctxt.LinkMode == ld.LinkExternal {
-				ld.Machoemitreloc(ctxt)
-			}
-		}
-	}
-
-	ctxt.Out.SeekSet(0)
-	switch ctxt.HeadType {
-	default:
-	case objabi.Hplan9: /* plan9 */
-		magic := int32(4*26*26 + 7)
-
-		magic |= 0x00008000                           /* fat header */
-		ctxt.Out.Write32b(uint32(magic))              /* magic */
-		ctxt.Out.Write32b(uint32(ld.Segtext.Filelen)) /* sizes */
-		ctxt.Out.Write32b(uint32(ld.Segdata.Filelen))
-		ctxt.Out.Write32b(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-		ctxt.Out.Write32b(uint32(ld.Symsize)) /* nsyms */
-		vl := ld.Entryvalue(ctxt)
-		ctxt.Out.Write32b(PADDR(uint32(vl))) /* va of entry */
-		ctxt.Out.Write32b(uint32(ld.Spsize)) /* sp offsets */
-		ctxt.Out.Write32b(uint32(ld.Lcsize)) /* line offsets */
-		ctxt.Out.Write64b(uint64(vl))        /* va of entry */
-
-	case objabi.Hdarwin:
-		ld.Asmbmacho(ctxt)
-
-	case objabi.Hlinux,
-		objabi.Hfreebsd,
-		objabi.Hnetbsd,
-		objabi.Hopenbsd,
-		objabi.Hdragonfly,
-		objabi.Hsolaris:
-		ld.Asmbelf(ctxt, symo)
-
-	case objabi.Hwindows:
-		ld.Asmbpe(ctxt)
-	}
-
-	ctxt.Out.Flush()
-}
-
-func tlsIEtoLE(s *sym.Symbol, off, size int) {
-	// Transform the PC-relative instruction into a constant load.
-	// That is,
-	//
-	//	MOVQ X(IP), REG  ->  MOVQ $Y, REG
-	//
-	// To determine the instruction and register, we study the op codes.
-	// Consult an AMD64 instruction encoding guide to decipher this.
-	if off < 3 {
-		log.Fatal("R_X86_64_GOTTPOFF reloc not preceded by MOVQ or ADDQ instruction")
-	}
-	op := s.P[off-3 : off]
-	reg := op[2] >> 3
-
-	if op[1] == 0x8b || reg == 4 {
-		// MOVQ
-		if op[0] == 0x4c {
-			op[0] = 0x49
-		} else if size == 4 && op[0] == 0x44 {
-			op[0] = 0x41
-		}
-		if op[1] == 0x8b {
-			op[1] = 0xc7
-		} else {
-			op[1] = 0x81 // special case for SP
-		}
-		op[2] = 0xc0 | reg
-	} else {
-		// An alternate op is ADDQ. This is handled by GNU gold,
-		// but right now is not generated by the Go compiler:
-		//	ADDQ X(IP), REG  ->  ADDQ $Y, REG
-		// Consider adding support for it here.
-		log.Fatalf("expected TLS IE op to be MOVQ, got %v", op)
-	}
-}
diff --git a/src/cmd/oldlink/internal/amd64/l.go b/src/cmd/oldlink/internal/amd64/l.go
deleted file mode 100644
index 393da6b..0000000
--- a/src/cmd/oldlink/internal/amd64/l.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Inferno utils/6l/l.h
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package amd64
-
-const (
-	maxAlign  = 32 // max data alignment
-	minAlign  = 1  // min data alignment
-	funcAlign = 16
-)
-
-/* Used by ../internal/ld/dwarf.go */
-const (
-	dwarfRegSP = 7
-	dwarfRegLR = 16
-)
diff --git a/src/cmd/oldlink/internal/amd64/obj.go b/src/cmd/oldlink/internal/amd64/obj.go
deleted file mode 100644
index 655d9f1..0000000
--- a/src/cmd/oldlink/internal/amd64/obj.go
+++ /dev/null
@@ -1,117 +0,0 @@
-// Inferno utils/6l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package amd64
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-	arch := sys.ArchAMD64
-
-	theArch := ld.Arch{
-		Funcalign:  funcAlign,
-		Maxalign:   maxAlign,
-		Minalign:   minAlign,
-		Dwarfregsp: dwarfRegSP,
-		Dwarfreglr: dwarfRegLR,
-
-		Adddynrel:        adddynrel,
-		Archinit:         archinit,
-		Archreloc:        archreloc,
-		Archrelocvariant: archrelocvariant,
-		Asmb:             asmb,
-		Asmb2:            asmb2,
-		Elfreloc1:        elfreloc1,
-		Elfsetupplt:      elfsetupplt,
-		Gentext:          gentext,
-		Machoreloc1:      machoreloc1,
-		PEreloc1:         pereloc1,
-		TLSIEtoLE:        tlsIEtoLE,
-
-		Linuxdynld:     "/lib64/ld-linux-x86-64.so.2",
-		Freebsddynld:   "/libexec/ld-elf.so.1",
-		Openbsddynld:   "/usr/libexec/ld.so",
-		Netbsddynld:    "/libexec/ld.elf_so",
-		Dragonflydynld: "/usr/libexec/ld-elf.so.2",
-		Solarisdynld:   "/lib/amd64/ld.so.1",
-	}
-
-	return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-	switch ctxt.HeadType {
-	default:
-		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-
-	case objabi.Hplan9: /* plan 9 */
-		ld.HEADR = 32 + 8
-
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 0x200000 + int64(ld.HEADR)
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 0x200000
-		}
-
-	case objabi.Hdarwin: /* apple MACH */
-		ld.HEADR = ld.INITIAL_MACHO_HEADR
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 4096
-		}
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 0x1000000 + int64(ld.HEADR)
-		}
-
-	case objabi.Hlinux, /* elf64 executable */
-		objabi.Hfreebsd,   /* freebsd */
-		objabi.Hnetbsd,    /* netbsd */
-		objabi.Hopenbsd,   /* openbsd */
-		objabi.Hdragonfly, /* dragonfly */
-		objabi.Hsolaris:   /* solaris */
-		ld.Elfinit(ctxt)
-
-		ld.HEADR = ld.ELFRESERVE
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = (1 << 22) + int64(ld.HEADR)
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 4096
-		}
-
-	case objabi.Hwindows: /* PE executable */
-		// ld.HEADR, ld.FlagTextAddr, ld.FlagRound are set in ld.Peinit
-		return
-	}
-}
diff --git a/src/cmd/oldlink/internal/arm/asm.go b/src/cmd/oldlink/internal/arm/asm.go
deleted file mode 100644
index de61735..0000000
--- a/src/cmd/oldlink/internal/arm/asm.go
+++ /dev/null
@@ -1,786 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package arm
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-	"cmd/oldlink/internal/sym"
-	"debug/elf"
-	"fmt"
-	"log"
-)
-
-// This assembler:
-//
-//         .align 2
-// local.dso_init:
-//         ldr r0, .Lmoduledata
-// .Lloadfrom:
-//         ldr r0, [r0]
-//         b runtime.addmoduledata@plt
-// .align 2
-// .Lmoduledata:
-//         .word local.moduledata(GOT_PREL) + (. - (.Lloadfrom + 4))
-// assembles to:
-//
-// 00000000 <local.dso_init>:
-//    0:        e59f0004        ldr     r0, [pc, #4]    ; c <local.dso_init+0xc>
-//    4:        e5900000        ldr     r0, [r0]
-//    8:        eafffffe        b       0 <runtime.addmoduledata>
-//                      8: R_ARM_JUMP24 runtime.addmoduledata
-//    c:        00000004        .word   0x00000004
-//                      c: R_ARM_GOT_PREL       local.moduledata
-
-func gentext(ctxt *ld.Link) {
-	if !ctxt.DynlinkingGo() {
-		return
-	}
-	addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-	if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
-		// we're linking a module containing the runtime -> no need for
-		// an init function
-		return
-	}
-	addmoduledata.Attr |= sym.AttrReachable
-	initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-	initfunc.Type = sym.STEXT
-	initfunc.Attr |= sym.AttrLocal
-	initfunc.Attr |= sym.AttrReachable
-	o := func(op uint32) {
-		initfunc.AddUint32(ctxt.Arch, op)
-	}
-	o(0xe59f0004)
-	o(0xe08f0000)
-
-	o(0xeafffffe)
-	rel := initfunc.AddRel()
-	rel.Off = 8
-	rel.Siz = 4
-	rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-	rel.Type = objabi.R_CALLARM
-	rel.Add = 0xeafffffe // vomit
-
-	o(0x00000000)
-	rel = initfunc.AddRel()
-	rel.Off = 12
-	rel.Siz = 4
-	rel.Sym = ctxt.Moduledata
-	rel.Type = objabi.R_PCREL
-	rel.Add = 4
-
-	if ctxt.BuildMode == ld.BuildModePlugin {
-		ctxt.Textp = append(ctxt.Textp, addmoduledata)
-	}
-	ctxt.Textp = append(ctxt.Textp, initfunc)
-	initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-	initarray_entry.Attr |= sym.AttrReachable
-	initarray_entry.Attr |= sym.AttrLocal
-	initarray_entry.Type = sym.SINITARR
-	initarray_entry.AddAddr(ctxt.Arch, initfunc)
-}
-
-// Preserve highest 8 bits of a, and do addition to lower 24-bit
-// of a and b; used to adjust ARM branch instruction's target
-func braddoff(a int32, b int32) int32 {
-	return int32((uint32(a))&0xff000000 | 0x00ffffff&uint32(a+b))
-}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-	targ := r.Sym
-
-	switch r.Type {
-	default:
-		if r.Type >= objabi.ElfRelocOffset {
-			ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
-			return false
-		}
-
-		// Handle relocations found in ELF object files.
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PLT32):
-		r.Type = objabi.R_CALLARM
-
-		if targ.Type == sym.SDYNIMPORT {
-			addpltsym(ctxt, targ)
-			r.Sym = ctxt.Syms.Lookup(".plt", 0)
-			r.Add = int64(braddoff(int32(r.Add), targ.Plt()/4))
-		}
-
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_THM_PC22): // R_ARM_THM_CALL
-		ld.Exitf("R_ARM_THM_CALL, are you using -marm?")
-		return false
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOT32): // R_ARM_GOT_BREL
-		if targ.Type != sym.SDYNIMPORT {
-			addgotsyminternal(ctxt, targ)
-		} else {
-			addgotsym(ctxt, targ)
-		}
-
-		r.Type = objabi.R_CONST // write r->add during relocsym
-		r.Sym = nil
-		r.Add += int64(targ.Got())
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOT_PREL): // GOT(nil) + A - nil
-		if targ.Type != sym.SDYNIMPORT {
-			addgotsyminternal(ctxt, targ)
-		} else {
-			addgotsym(ctxt, targ)
-		}
-
-		r.Type = objabi.R_PCREL
-		r.Sym = ctxt.Syms.Lookup(".got", 0)
-		r.Add += int64(targ.Got()) + 4
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOTOFF): // R_ARM_GOTOFF32
-		r.Type = objabi.R_GOTOFF
-
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOTPC): // R_ARM_BASE_PREL
-		r.Type = objabi.R_PCREL
-
-		r.Sym = ctxt.Syms.Lookup(".got", 0)
-		r.Add += 4
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_CALL):
-		r.Type = objabi.R_CALLARM
-		if targ.Type == sym.SDYNIMPORT {
-			addpltsym(ctxt, targ)
-			r.Sym = ctxt.Syms.Lookup(".plt", 0)
-			r.Add = int64(braddoff(int32(r.Add), targ.Plt()/4))
-		}
-
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_REL32): // R_ARM_REL32
-		r.Type = objabi.R_PCREL
-
-		r.Add += 4
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_ABS32):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected R_ARM_ABS32 relocation for dynamic symbol %s", targ.Name)
-		}
-		r.Type = objabi.R_ADDR
-		return true
-
-		// we can just ignore this, because we are targeting ARM V5+ anyway
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_V4BX):
-		if r.Sym != nil {
-			// R_ARM_V4BX is ABS relocation, so this symbol is a dummy symbol, ignore it
-			r.Sym.Type = 0
-		}
-
-		r.Sym = nil
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PC24),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_JUMP24):
-		r.Type = objabi.R_CALLARM
-		if targ.Type == sym.SDYNIMPORT {
-			addpltsym(ctxt, targ)
-			r.Sym = ctxt.Syms.Lookup(".plt", 0)
-			r.Add = int64(braddoff(int32(r.Add), targ.Plt()/4))
-		}
-
-		return true
-	}
-
-	// Handle references to ELF symbols from our own object files.
-	if targ.Type != sym.SDYNIMPORT {
-		return true
-	}
-
-	switch r.Type {
-	case objabi.R_CALLARM:
-		if ctxt.LinkMode == ld.LinkExternal {
-			// External linker will do this relocation.
-			return true
-		}
-		addpltsym(ctxt, targ)
-		r.Sym = ctxt.Syms.Lookup(".plt", 0)
-		r.Add = int64(targ.Plt())
-		return true
-
-	case objabi.R_ADDR:
-		if s.Type != sym.SDATA {
-			break
-		}
-		if ctxt.IsELF {
-			ld.Adddynsym(ctxt, targ)
-			rel := ctxt.Syms.Lookup(".rel", 0)
-			rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
-			rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_ARM_GLOB_DAT))) // we need a nil + A dynamic reloc
-			r.Type = objabi.R_CONST                                                                   // write r->add during relocsym
-			r.Sym = nil
-			return true
-		}
-	}
-
-	return false
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-	ctxt.Out.Write32(uint32(sectoff))
-
-	elfsym := r.Xsym.ElfsymForReloc()
-	switch r.Type {
-	default:
-		return false
-	case objabi.R_ADDR:
-		if r.Siz == 4 {
-			ctxt.Out.Write32(uint32(elf.R_ARM_ABS32) | uint32(elfsym)<<8)
-		} else {
-			return false
-		}
-	case objabi.R_PCREL:
-		if r.Siz == 4 {
-			ctxt.Out.Write32(uint32(elf.R_ARM_REL32) | uint32(elfsym)<<8)
-		} else {
-			return false
-		}
-	case objabi.R_CALLARM:
-		if r.Siz == 4 {
-			if r.Add&0xff000000 == 0xeb000000 { // BL
-				ctxt.Out.Write32(uint32(elf.R_ARM_CALL) | uint32(elfsym)<<8)
-			} else {
-				ctxt.Out.Write32(uint32(elf.R_ARM_JUMP24) | uint32(elfsym)<<8)
-			}
-		} else {
-			return false
-		}
-	case objabi.R_TLS_LE:
-		ctxt.Out.Write32(uint32(elf.R_ARM_TLS_LE32) | uint32(elfsym)<<8)
-	case objabi.R_TLS_IE:
-		ctxt.Out.Write32(uint32(elf.R_ARM_TLS_IE32) | uint32(elfsym)<<8)
-	case objabi.R_GOTPCREL:
-		if r.Siz == 4 {
-			ctxt.Out.Write32(uint32(elf.R_ARM_GOT_PREL) | uint32(elfsym)<<8)
-		} else {
-			return false
-		}
-	}
-
-	return true
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-	plt := ctxt.Syms.Lookup(".plt", 0)
-	got := ctxt.Syms.Lookup(".got.plt", 0)
-	if plt.Size == 0 {
-		// str lr, [sp, #-4]!
-		plt.AddUint32(ctxt.Arch, 0xe52de004)
-
-		// ldr lr, [pc, #4]
-		plt.AddUint32(ctxt.Arch, 0xe59fe004)
-
-		// add lr, pc, lr
-		plt.AddUint32(ctxt.Arch, 0xe08fe00e)
-
-		// ldr pc, [lr, #8]!
-		plt.AddUint32(ctxt.Arch, 0xe5bef008)
-
-		// .word &GLOBAL_OFFSET_TABLE[0] - .
-		plt.AddPCRelPlus(ctxt.Arch, got, 4)
-
-		// the first .plt entry requires 3 .plt.got entries
-		got.AddUint32(ctxt.Arch, 0)
-
-		got.AddUint32(ctxt.Arch, 0)
-		got.AddUint32(ctxt.Arch, 0)
-	}
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-	return false
-}
-
-func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-	rs := r.Xsym
-
-	if rs.Dynid < 0 {
-		ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
-		return false
-	}
-
-	out.Write32(uint32(sectoff))
-	out.Write32(uint32(rs.Dynid))
-
-	var v uint32
-	switch r.Type {
-	default:
-		// unsupported relocation type
-		return false
-
-	case objabi.R_DWARFSECREF:
-		v = ld.IMAGE_REL_ARM_SECREL
-
-	case objabi.R_ADDR:
-		v = ld.IMAGE_REL_ARM_ADDR32
-	}
-
-	out.Write16(uint16(v))
-
-	return true
-}
-
-// sign extend a 24-bit integer
-func signext24(x int64) int32 {
-	return (int32(x) << 8) >> 8
-}
-
-// encode an immediate in ARM's imm12 format. copied from ../../../internal/obj/arm/asm5.go
-func immrot(v uint32) uint32 {
-	for i := 0; i < 16; i++ {
-		if v&^0xff == 0 {
-			return uint32(i<<8) | v | 1<<25
-		}
-		v = v<<2 | v>>30
-	}
-	return 0
-}
-
-// Convert the direct jump relocation r to refer to a trampoline if the target is too far
-func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
-	switch r.Type {
-	case objabi.R_CALLARM:
-		// r.Add is the instruction
-		// low 24-bit encodes the target address
-		t := (ld.Symaddr(r.Sym) + int64(signext24(r.Add&0xffffff)*4) - (s.Value + int64(r.Off))) / 4
-		if t > 0x7fffff || t < -0x800000 || (*ld.FlagDebugTramp > 1 && s.File != r.Sym.File) {
-			// direct call too far, need to insert trampoline.
-			// look up existing trampolines first. if we found one within the range
-			// of direct call, we can reuse it. otherwise create a new one.
-			offset := (signext24(r.Add&0xffffff) + 2) * 4
-			var tramp *sym.Symbol
-			for i := 0; ; i++ {
-				name := r.Sym.Name + fmt.Sprintf("%+d-tramp%d", offset, i)
-				tramp = ctxt.Syms.Lookup(name, int(r.Sym.Version))
-				if tramp.Type == sym.SDYNIMPORT {
-					// don't reuse trampoline defined in other module
-					continue
-				}
-				if tramp.Value == 0 {
-					// either the trampoline does not exist -- we need to create one,
-					// or found one the address which is not assigned -- this will be
-					// laid down immediately after the current function. use this one.
-					break
-				}
-
-				t = (ld.Symaddr(tramp) - 8 - (s.Value + int64(r.Off))) / 4
-				if t >= -0x800000 && t < 0x7fffff {
-					// found an existing trampoline that is not too far
-					// we can just use it
-					break
-				}
-			}
-			if tramp.Type == 0 {
-				// trampoline does not exist, create one
-				ctxt.AddTramp(tramp)
-				if ctxt.DynlinkingGo() {
-					if immrot(uint32(offset)) == 0 {
-						ld.Errorf(s, "odd offset in dynlink direct call: %v+%d", r.Sym, offset)
-					}
-					gentrampdyn(ctxt.Arch, tramp, r.Sym, int64(offset))
-				} else if ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE {
-					gentramppic(ctxt.Arch, tramp, r.Sym, int64(offset))
-				} else {
-					gentramp(ctxt.Arch, ctxt.LinkMode, tramp, r.Sym, int64(offset))
-				}
-			}
-			// modify reloc to point to tramp, which will be resolved later
-			r.Sym = tramp
-			r.Add = r.Add&0xff000000 | 0xfffffe // clear the offset embedded in the instruction
-			r.Done = false
-		}
-	default:
-		ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
-	}
-}
-
-// generate a trampoline to target+offset
-func gentramp(arch *sys.Arch, linkmode ld.LinkMode, tramp, target *sym.Symbol, offset int64) {
-	tramp.Size = 12 // 3 instructions
-	tramp.P = make([]byte, tramp.Size)
-	t := ld.Symaddr(target) + offset
-	o1 := uint32(0xe5900000 | 11<<12 | 15<<16) // MOVW (R15), R11 // R15 is actual pc + 8
-	o2 := uint32(0xe12fff10 | 11)              // JMP  (R11)
-	o3 := uint32(t)                            // WORD $target
-	arch.ByteOrder.PutUint32(tramp.P, o1)
-	arch.ByteOrder.PutUint32(tramp.P[4:], o2)
-	arch.ByteOrder.PutUint32(tramp.P[8:], o3)
-
-	if linkmode == ld.LinkExternal {
-		r := tramp.AddRel()
-		r.Off = 8
-		r.Type = objabi.R_ADDR
-		r.Siz = 4
-		r.Sym = target
-		r.Add = offset
-	}
-}
-
-// generate a trampoline to target+offset in position independent code
-func gentramppic(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
-	tramp.Size = 16 // 4 instructions
-	tramp.P = make([]byte, tramp.Size)
-	o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 4)  // MOVW 4(R15), R11 // R15 is actual pc + 8
-	o2 := uint32(0xe0800000 | 11<<12 | 15<<16 | 11) // ADD R15, R11, R11
-	o3 := uint32(0xe12fff10 | 11)                   // JMP  (R11)
-	o4 := uint32(0)                                 // WORD $(target-pc) // filled in with relocation
-	arch.ByteOrder.PutUint32(tramp.P, o1)
-	arch.ByteOrder.PutUint32(tramp.P[4:], o2)
-	arch.ByteOrder.PutUint32(tramp.P[8:], o3)
-	arch.ByteOrder.PutUint32(tramp.P[12:], o4)
-
-	r := tramp.AddRel()
-	r.Off = 12
-	r.Type = objabi.R_PCREL
-	r.Siz = 4
-	r.Sym = target
-	r.Add = offset + 4
-}
-
-// generate a trampoline to target+offset in dynlink mode (using GOT)
-func gentrampdyn(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
-	tramp.Size = 20                                 // 5 instructions
-	o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 8)  // MOVW 8(R15), R11 // R15 is actual pc + 8
-	o2 := uint32(0xe0800000 | 11<<12 | 15<<16 | 11) // ADD R15, R11, R11
-	o3 := uint32(0xe5900000 | 11<<12 | 11<<16)      // MOVW (R11), R11
-	o4 := uint32(0xe12fff10 | 11)                   // JMP  (R11)
-	o5 := uint32(0)                                 // WORD $target@GOT // filled in with relocation
-	o6 := uint32(0)
-	if offset != 0 {
-		// insert an instruction to add offset
-		tramp.Size = 24 // 6 instructions
-		o6 = o5
-		o5 = o4
-		o4 = 0xe2800000 | 11<<12 | 11<<16 | immrot(uint32(offset)) // ADD $offset, R11, R11
-		o1 = uint32(0xe5900000 | 11<<12 | 15<<16 | 12)             // MOVW 12(R15), R11
-	}
-	tramp.P = make([]byte, tramp.Size)
-	arch.ByteOrder.PutUint32(tramp.P, o1)
-	arch.ByteOrder.PutUint32(tramp.P[4:], o2)
-	arch.ByteOrder.PutUint32(tramp.P[8:], o3)
-	arch.ByteOrder.PutUint32(tramp.P[12:], o4)
-	arch.ByteOrder.PutUint32(tramp.P[16:], o5)
-	if offset != 0 {
-		arch.ByteOrder.PutUint32(tramp.P[20:], o6)
-	}
-
-	r := tramp.AddRel()
-	r.Off = 16
-	r.Type = objabi.R_GOTPCREL
-	r.Siz = 4
-	r.Sym = target
-	r.Add = 8
-	if offset != 0 {
-		// increase reloc offset by 4 as we inserted an ADD instruction
-		r.Off = 20
-		r.Add = 12
-	}
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-	if ctxt.LinkMode == ld.LinkExternal {
-		switch r.Type {
-		case objabi.R_CALLARM:
-			r.Done = false
-
-			// set up addend for eventual relocation via outer symbol.
-			rs := r.Sym
-
-			r.Xadd = int64(signext24(r.Add & 0xffffff))
-			r.Xadd *= 4
-			for rs.Outer != nil {
-				r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
-				rs = rs.Outer
-			}
-
-			if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Type != sym.SUNDEFEXT && rs.Sect == nil {
-				ld.Errorf(s, "missing section for %s", rs.Name)
-			}
-			r.Xsym = rs
-
-			if r.Xadd/4 > 0x7fffff || r.Xadd/4 < -0x800000 {
-				ld.Errorf(s, "direct call too far %d", r.Xadd/4)
-			}
-
-			return int64(braddoff(int32(0xff000000&uint32(r.Add)), int32(0xffffff&uint32(r.Xadd/4)))), true
-		}
-
-		return -1, false
-	}
-
-	switch r.Type {
-	case objabi.R_CONST:
-		return r.Add, true
-	case objabi.R_GOTOFF:
-		return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
-
-	// The following three arch specific relocations are only for generation of
-	// Linux/ARM ELF's PLT entry (3 assembler instruction)
-	case objabi.R_PLT0: // add ip, pc, #0xXX00000
-		if ld.Symaddr(ctxt.Syms.Lookup(".got.plt", 0)) < ld.Symaddr(ctxt.Syms.Lookup(".plt", 0)) {
-			ld.Errorf(s, ".got.plt should be placed after .plt section.")
-		}
-		return 0xe28fc600 + (0xff & (int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add)) >> 20)), true
-	case objabi.R_PLT1: // add ip, ip, #0xYY000
-		return 0xe28cca00 + (0xff & (int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add+4)) >> 12)), true
-	case objabi.R_PLT2: // ldr pc, [ip, #0xZZZ]!
-		return 0xe5bcf000 + (0xfff & int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add+8))), true
-	case objabi.R_CALLARM: // bl XXXXXX or b YYYYYY
-		// r.Add is the instruction
-		// low 24-bit encodes the target address
-		t := (ld.Symaddr(r.Sym) + int64(signext24(r.Add&0xffffff)*4) - (s.Value + int64(r.Off))) / 4
-		if t > 0x7fffff || t < -0x800000 {
-			ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
-		}
-		return int64(braddoff(int32(0xff000000&uint32(r.Add)), int32(0xffffff&t))), true
-	}
-
-	return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-	log.Fatalf("unexpected relocation variant")
-	return t
-}
-
-func addpltreloc(ctxt *ld.Link, plt *sym.Symbol, got *sym.Symbol, s *sym.Symbol, typ objabi.RelocType) {
-	r := plt.AddRel()
-	r.Sym = got
-	r.Off = int32(plt.Size)
-	r.Siz = 4
-	r.Type = typ
-	r.Add = int64(s.Got()) - 8
-
-	plt.Attr |= sym.AttrReachable
-	plt.Size += 4
-	plt.Grow(plt.Size)
-}
-
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
-	if s.Plt() >= 0 {
-		return
-	}
-
-	ld.Adddynsym(ctxt, s)
-
-	if ctxt.IsELF {
-		plt := ctxt.Syms.Lookup(".plt", 0)
-		got := ctxt.Syms.Lookup(".got.plt", 0)
-		rel := ctxt.Syms.Lookup(".rel.plt", 0)
-		if plt.Size == 0 {
-			elfsetupplt(ctxt)
-		}
-
-		// .got entry
-		s.SetGot(int32(got.Size))
-
-		// In theory, all GOT should point to the first PLT entry,
-		// Linux/ARM's dynamic linker will do that for us, but FreeBSD/ARM's
-		// dynamic linker won't, so we'd better do it ourselves.
-		got.AddAddrPlus(ctxt.Arch, plt, 0)
-
-		// .plt entry, this depends on the .got entry
-		s.SetPlt(int32(plt.Size))
-
-		addpltreloc(ctxt, plt, got, s, objabi.R_PLT0) // add lr, pc, #0xXX00000
-		addpltreloc(ctxt, plt, got, s, objabi.R_PLT1) // add lr, lr, #0xYY000
-		addpltreloc(ctxt, plt, got, s, objabi.R_PLT2) // ldr pc, [lr, #0xZZZ]!
-
-		// rel
-		rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
-
-		rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_JUMP_SLOT)))
-	} else {
-		ld.Errorf(s, "addpltsym: unsupported binary format")
-	}
-}
-
-func addgotsyminternal(ctxt *ld.Link, s *sym.Symbol) {
-	if s.Got() >= 0 {
-		return
-	}
-
-	got := ctxt.Syms.Lookup(".got", 0)
-	s.SetGot(int32(got.Size))
-
-	got.AddAddrPlus(ctxt.Arch, s, 0)
-
-	if ctxt.IsELF {
-	} else {
-		ld.Errorf(s, "addgotsyminternal: unsupported binary format")
-	}
-}
-
-func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
-	if s.Got() >= 0 {
-		return
-	}
-
-	ld.Adddynsym(ctxt, s)
-	got := ctxt.Syms.Lookup(".got", 0)
-	s.SetGot(int32(got.Size))
-	got.AddUint32(ctxt.Arch, 0)
-
-	if ctxt.IsELF {
-		rel := ctxt.Syms.Lookup(".rel", 0)
-		rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
-		rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_GLOB_DAT)))
-	} else {
-		ld.Errorf(s, "addgotsym: unsupported binary format")
-	}
-}
-
-func asmb(ctxt *ld.Link) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	sect := ld.Segtext.Sections[0]
-	ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-	ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-	for _, sect = range ld.Segtext.Sections[1:] {
-		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-		ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-	}
-	if ld.Segrelrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
-	}
-
-	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-	/* output symbol table */
-	ld.Symsize = 0
-
-	ld.Lcsize = 0
-	symo := uint32(0)
-	if !*ld.FlagS {
-		// TODO: rationalize
-		switch ctxt.HeadType {
-		default:
-			if ctxt.IsELF {
-				symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-				symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
-			}
-
-		case objabi.Hplan9:
-			symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
-
-		case objabi.Hwindows:
-			symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-			symo = uint32(ld.Rnd(int64(symo), ld.PEFILEALIGN))
-		}
-
-		ctxt.Out.SeekSet(int64(symo))
-		switch ctxt.HeadType {
-		default:
-			if ctxt.IsELF {
-				ld.Asmelfsym(ctxt)
-				ctxt.Out.Flush()
-				ctxt.Out.Write(ld.Elfstrdat)
-
-				if ctxt.LinkMode == ld.LinkExternal {
-					ld.Elfemitreloc(ctxt)
-				}
-			}
-
-		case objabi.Hplan9:
-			ld.Asmplan9sym(ctxt)
-			ctxt.Out.Flush()
-
-			sym := ctxt.Syms.Lookup("pclntab", 0)
-			if sym != nil {
-				ld.Lcsize = int32(len(sym.P))
-				ctxt.Out.Write(sym.P)
-				ctxt.Out.Flush()
-			}
-
-		case objabi.Hwindows:
-			// Do nothing
-		}
-	}
-
-	ctxt.Out.SeekSet(0)
-	switch ctxt.HeadType {
-	default:
-	case objabi.Hplan9: /* plan 9 */
-		ctxt.Out.Write32b(0x647)                      /* magic */
-		ctxt.Out.Write32b(uint32(ld.Segtext.Filelen)) /* sizes */
-		ctxt.Out.Write32b(uint32(ld.Segdata.Filelen))
-		ctxt.Out.Write32b(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-		ctxt.Out.Write32b(uint32(ld.Symsize))          /* nsyms */
-		ctxt.Out.Write32b(uint32(ld.Entryvalue(ctxt))) /* va of entry */
-		ctxt.Out.Write32b(0)
-		ctxt.Out.Write32b(uint32(ld.Lcsize))
-
-	case objabi.Hlinux,
-		objabi.Hfreebsd,
-		objabi.Hnetbsd,
-		objabi.Hopenbsd:
-		ld.Asmbelf(ctxt, int64(symo))
-
-	case objabi.Hwindows:
-		ld.Asmbpe(ctxt)
-	}
-
-	ctxt.Out.Flush()
-	if *ld.FlagC {
-		fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
-		fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
-		fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
-		fmt.Printf("symsize=%d\n", ld.Symsize)
-		fmt.Printf("lcsize=%d\n", ld.Lcsize)
-		fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
-	}
-}
diff --git a/src/cmd/oldlink/internal/arm/l.go b/src/cmd/oldlink/internal/arm/l.go
deleted file mode 100644
index a83d26b..0000000
--- a/src/cmd/oldlink/internal/arm/l.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package arm
-
-// Writing object files.
-
-// Inferno utils/5l/l.h
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/l.h
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-const (
-	maxAlign  = 8 // max data alignment
-	minAlign  = 1 // min data alignment
-	funcAlign = 4 // single-instruction alignment
-)
-
-/* Used by ../internal/ld/dwarf.go */
-const (
-	dwarfRegSP = 13
-	dwarfRegLR = 14
-)
diff --git a/src/cmd/oldlink/internal/arm/obj.go b/src/cmd/oldlink/internal/arm/obj.go
deleted file mode 100644
index c423937..0000000
--- a/src/cmd/oldlink/internal/arm/obj.go
+++ /dev/null
@@ -1,107 +0,0 @@
-// Inferno utils/5l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/obj.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package arm
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-	arch := sys.ArchARM
-
-	theArch := ld.Arch{
-		Funcalign:  funcAlign,
-		Maxalign:   maxAlign,
-		Minalign:   minAlign,
-		Dwarfregsp: dwarfRegSP,
-		Dwarfreglr: dwarfRegLR,
-
-		Adddynrel:        adddynrel,
-		Archinit:         archinit,
-		Archreloc:        archreloc,
-		Archrelocvariant: archrelocvariant,
-		Trampoline:       trampoline,
-		Asmb:             asmb,
-		Asmb2:            asmb2,
-		Elfreloc1:        elfreloc1,
-		Elfsetupplt:      elfsetupplt,
-		Gentext:          gentext,
-		Machoreloc1:      machoreloc1,
-		PEreloc1:         pereloc1,
-
-		Linuxdynld:     "/lib/ld-linux.so.3", // 2 for OABI, 3 for EABI
-		Freebsddynld:   "/usr/libexec/ld-elf.so.1",
-		Openbsddynld:   "/usr/libexec/ld.so",
-		Netbsddynld:    "/libexec/ld.elf_so",
-		Dragonflydynld: "XXX",
-		Solarisdynld:   "XXX",
-	}
-
-	return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-	switch ctxt.HeadType {
-	default:
-		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-
-	case objabi.Hplan9: /* plan 9 */
-		ld.HEADR = 32
-
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 4128
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 4096
-		}
-
-	case objabi.Hlinux, /* arm elf */
-		objabi.Hfreebsd,
-		objabi.Hnetbsd,
-		objabi.Hopenbsd:
-		*ld.FlagD = false
-		// with dynamic linking
-		ld.Elfinit(ctxt)
-		ld.HEADR = ld.ELFRESERVE
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 0x10000
-		}
-
-	case objabi.Hwindows: /* PE executable */
-		// ld.HEADR, ld.FlagTextAddr, ld.FlagRound are set in ld.Peinit
-		return
-	}
-}
diff --git a/src/cmd/oldlink/internal/arm64/asm.go b/src/cmd/oldlink/internal/arm64/asm.go
deleted file mode 100644
index a976712..0000000
--- a/src/cmd/oldlink/internal/arm64/asm.go
+++ /dev/null
@@ -1,946 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package arm64
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-	"cmd/oldlink/internal/sym"
-	"debug/elf"
-	"encoding/binary"
-	"fmt"
-	"log"
-)
-
-func gentext(ctxt *ld.Link) {
-	if !ctxt.DynlinkingGo() {
-		return
-	}
-	addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-	if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
-		// we're linking a module containing the runtime -> no need for
-		// an init function
-		return
-	}
-	addmoduledata.Attr |= sym.AttrReachable
-	initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-	initfunc.Type = sym.STEXT
-	initfunc.Attr |= sym.AttrLocal
-	initfunc.Attr |= sym.AttrReachable
-	o := func(op uint32) {
-		initfunc.AddUint32(ctxt.Arch, op)
-	}
-	// 0000000000000000 <local.dso_init>:
-	// 0:	90000000 	adrp	x0, 0 <runtime.firstmoduledata>
-	// 	0: R_AARCH64_ADR_PREL_PG_HI21	local.moduledata
-	// 4:	91000000 	add	x0, x0, #0x0
-	// 	4: R_AARCH64_ADD_ABS_LO12_NC	local.moduledata
-	o(0x90000000)
-	o(0x91000000)
-	rel := initfunc.AddRel()
-	rel.Off = 0
-	rel.Siz = 8
-	rel.Sym = ctxt.Moduledata
-	rel.Type = objabi.R_ADDRARM64
-
-	// 8:	14000000 	b	0 <runtime.addmoduledata>
-	// 	8: R_AARCH64_CALL26	runtime.addmoduledata
-	o(0x14000000)
-	rel = initfunc.AddRel()
-	rel.Off = 8
-	rel.Siz = 4
-	rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-	rel.Type = objabi.R_CALLARM64 // Really should be R_AARCH64_JUMP26 but doesn't seem to make any difference
-
-	if ctxt.BuildMode == ld.BuildModePlugin {
-		ctxt.Textp = append(ctxt.Textp, addmoduledata)
-	}
-	ctxt.Textp = append(ctxt.Textp, initfunc)
-	initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-	initarray_entry.Attr |= sym.AttrReachable
-	initarray_entry.Attr |= sym.AttrLocal
-	initarray_entry.Type = sym.SINITARR
-	initarray_entry.AddAddr(ctxt.Arch, initfunc)
-}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-	targ := r.Sym
-
-	switch r.Type {
-	default:
-		if r.Type >= objabi.ElfRelocOffset {
-			ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
-			return false
-		}
-
-	// Handle relocations found in ELF object files.
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_PREL32):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected R_AARCH64_PREL32 relocation for dynamic symbol %s", targ.Name)
-		}
-		// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
-		// sense and should be removed when someone has thought about it properly.
-		if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
-			ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
-		}
-		r.Type = objabi.R_PCREL
-		r.Add += 4
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_PREL64):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected R_AARCH64_PREL64 relocation for dynamic symbol %s", targ.Name)
-		}
-		if targ.Type == 0 || targ.Type == sym.SXREF {
-			ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
-		}
-		r.Type = objabi.R_PCREL
-		r.Add += 8
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_CALL26),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_JUMP26):
-		if targ.Type == sym.SDYNIMPORT {
-			addpltsym(ctxt, targ)
-			r.Sym = ctxt.Syms.Lookup(".plt", 0)
-			r.Add += int64(targ.Plt())
-		}
-		if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
-			ld.Errorf(s, "unknown symbol %s in callarm64", targ.Name)
-		}
-		r.Type = objabi.R_CALLARM64
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_ADR_GOT_PAGE),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_LD64_GOT_LO12_NC):
-		if targ.Type != sym.SDYNIMPORT {
-			// have symbol
-			// TODO: turn LDR of GOT entry into ADR of symbol itself
-		}
-
-		// fall back to using GOT
-		// TODO: just needs relocation, no need to put in .dynsym
-		addgotsym(ctxt, targ)
-
-		r.Type = objabi.R_ARM64_GOT
-		r.Sym = ctxt.Syms.Lookup(".got", 0)
-		r.Add += int64(targ.Got())
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_ADR_PREL_PG_HI21),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_ADD_ABS_LO12_NC):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
-		}
-		if targ.Type == 0 || targ.Type == sym.SXREF {
-			ld.Errorf(s, "unknown symbol %s", targ.Name)
-		}
-		r.Type = objabi.R_ARM64_PCREL
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_ABS64):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected R_AARCH64_ABS64 relocation for dynamic symbol %s", targ.Name)
-		}
-		r.Type = objabi.R_ADDR
-		if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal {
-			// For internal linking PIE, this R_ADDR relocation cannot
-			// be resolved statically. We need to generate a dynamic
-			// relocation. Let the code below handle it.
-			break
-		}
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_LDST8_ABS_LO12_NC):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
-		}
-		r.Type = objabi.R_ARM64_LDST8
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_LDST32_ABS_LO12_NC):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
-		}
-		r.Type = objabi.R_ARM64_LDST32
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_LDST64_ABS_LO12_NC):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
-		}
-		r.Type = objabi.R_ARM64_LDST64
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_LDST128_ABS_LO12_NC):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
-		}
-		r.Type = objabi.R_ARM64_LDST128
-		return true
-	}
-
-	switch r.Type {
-	case objabi.R_CALL,
-		objabi.R_PCREL,
-		objabi.R_CALLARM64:
-		if targ.Type != sym.SDYNIMPORT {
-			// nothing to do, the relocation will be laid out in reloc
-			return true
-		}
-		if ctxt.LinkMode == ld.LinkExternal {
-			// External linker will do this relocation.
-			return true
-		}
-
-	case objabi.R_ADDR:
-		if s.Type == sym.STEXT && ctxt.IsELF {
-			// The code is asking for the address of an external
-			// function. We provide it with the address of the
-			// correspondent GOT symbol.
-			addgotsym(ctxt, targ)
-
-			r.Sym = ctxt.Syms.Lookup(".got", 0)
-			r.Add += int64(targ.Got())
-			return true
-		}
-
-		// Process dynamic relocations for the data sections.
-		if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal {
-			// When internally linking, generate dynamic relocations
-			// for all typical R_ADDR relocations. The exception
-			// are those R_ADDR that are created as part of generating
-			// the dynamic relocations and must be resolved statically.
-			//
-			// There are three phases relevant to understanding this:
-			//
-			//	dodata()  // we are here
-			//	address() // symbol address assignment
-			//	reloc()   // resolution of static R_ADDR relocs
-			//
-			// At this point symbol addresses have not been
-			// assigned yet (as the final size of the .rela section
-			// will affect the addresses), and so we cannot write
-			// the Elf64_Rela.r_offset now. Instead we delay it
-			// until after the 'address' phase of the linker is
-			// complete. We do this via Addaddrplus, which creates
-			// a new R_ADDR relocation which will be resolved in
-			// the 'reloc' phase.
-			//
-			// These synthetic static R_ADDR relocs must be skipped
-			// now, or else we will be caught in an infinite loop
-			// of generating synthetic relocs for our synthetic
-			// relocs.
-			//
-			// Furthermore, the rela sections contain dynamic
-			// relocations with R_ADDR relocations on
-			// Elf64_Rela.r_offset. This field should contain the
-			// symbol offset as determined by reloc(), not the
-			// final dynamically linked address as a dynamic
-			// relocation would provide.
-			switch s.Name {
-			case ".dynsym", ".rela", ".rela.plt", ".got.plt", ".dynamic":
-				return false
-			}
-		} else {
-			// Either internally linking a static executable,
-			// in which case we can resolve these relocations
-			// statically in the 'reloc' phase, or externally
-			// linking, in which case the relocation will be
-			// prepared in the 'reloc' phase and passed to the
-			// external linker in the 'asmb' phase.
-			if s.Type != sym.SDATA && s.Type != sym.SRODATA {
-				break
-			}
-		}
-
-		if ctxt.IsELF {
-			// Generate R_AARCH64_RELATIVE relocations for best
-			// efficiency in the dynamic linker.
-			//
-			// As noted above, symbol addresses have not been
-			// assigned yet, so we can't generate the final reloc
-			// entry yet. We ultimately want:
-			//
-			// r_offset = s + r.Off
-			// r_info = R_AARCH64_RELATIVE
-			// r_addend = targ + r.Add
-			//
-			// The dynamic linker will set *offset = base address +
-			// addend.
-			//
-			// AddAddrPlus is used for r_offset and r_addend to
-			// generate new R_ADDR relocations that will update
-			// these fields in the 'reloc' phase.
-			rela := ctxt.Syms.Lookup(".rela", 0)
-			rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
-			if r.Siz == 8 {
-				rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_AARCH64_RELATIVE)))
-			} else {
-				ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
-			}
-			rela.AddAddrPlus(ctxt.Arch, targ, int64(r.Add))
-			// Not mark r done here. So we still apply it statically,
-			// so in the file content we'll also have the right offset
-			// to the relocation target. So it can be examined statically
-			// (e.g. go version).
-			return true
-		}
-	}
-	return false
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-	ctxt.Out.Write64(uint64(sectoff))
-
-	elfsym := r.Xsym.ElfsymForReloc()
-	switch r.Type {
-	default:
-		return false
-	case objabi.R_ADDR:
-		switch r.Siz {
-		case 4:
-			ctxt.Out.Write64(uint64(elf.R_AARCH64_ABS32) | uint64(elfsym)<<32)
-		case 8:
-			ctxt.Out.Write64(uint64(elf.R_AARCH64_ABS64) | uint64(elfsym)<<32)
-		default:
-			return false
-		}
-	case objabi.R_ADDRARM64:
-		// two relocations: R_AARCH64_ADR_PREL_PG_HI21 and R_AARCH64_ADD_ABS_LO12_NC
-		ctxt.Out.Write64(uint64(elf.R_AARCH64_ADR_PREL_PG_HI21) | uint64(elfsym)<<32)
-		ctxt.Out.Write64(uint64(r.Xadd))
-		ctxt.Out.Write64(uint64(sectoff + 4))
-		ctxt.Out.Write64(uint64(elf.R_AARCH64_ADD_ABS_LO12_NC) | uint64(elfsym)<<32)
-	case objabi.R_ARM64_TLS_LE:
-		ctxt.Out.Write64(uint64(elf.R_AARCH64_TLSLE_MOVW_TPREL_G0) | uint64(elfsym)<<32)
-	case objabi.R_ARM64_TLS_IE:
-		ctxt.Out.Write64(uint64(elf.R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) | uint64(elfsym)<<32)
-		ctxt.Out.Write64(uint64(r.Xadd))
-		ctxt.Out.Write64(uint64(sectoff + 4))
-		ctxt.Out.Write64(uint64(elf.R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) | uint64(elfsym)<<32)
-	case objabi.R_ARM64_GOTPCREL:
-		ctxt.Out.Write64(uint64(elf.R_AARCH64_ADR_GOT_PAGE) | uint64(elfsym)<<32)
-		ctxt.Out.Write64(uint64(r.Xadd))
-		ctxt.Out.Write64(uint64(sectoff + 4))
-		ctxt.Out.Write64(uint64(elf.R_AARCH64_LD64_GOT_LO12_NC) | uint64(elfsym)<<32)
-	case objabi.R_CALLARM64:
-		if r.Siz != 4 {
-			return false
-		}
-		ctxt.Out.Write64(uint64(elf.R_AARCH64_CALL26) | uint64(elfsym)<<32)
-
-	}
-	ctxt.Out.Write64(uint64(r.Xadd))
-
-	return true
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-	var v uint32
-
-	rs := r.Xsym
-
-	if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_CALLARM64 || r.Type == objabi.R_ADDRARM64 {
-		if rs.Dynid < 0 {
-			ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
-			return false
-		}
-
-		v = uint32(rs.Dynid)
-		v |= 1 << 27 // external relocation
-	} else {
-		v = uint32(rs.Sect.Extnum)
-		if v == 0 {
-			ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
-			return false
-		}
-	}
-
-	switch r.Type {
-	default:
-		return false
-	case objabi.R_ADDR:
-		v |= ld.MACHO_ARM64_RELOC_UNSIGNED << 28
-	case objabi.R_CALLARM64:
-		if r.Xadd != 0 {
-			ld.Errorf(s, "ld64 doesn't allow BR26 reloc with non-zero addend: %s+%d", rs.Name, r.Xadd)
-		}
-
-		v |= 1 << 24 // pc-relative bit
-		v |= ld.MACHO_ARM64_RELOC_BRANCH26 << 28
-	case objabi.R_ADDRARM64:
-		r.Siz = 4
-		// Two relocation entries: MACHO_ARM64_RELOC_PAGEOFF12 MACHO_ARM64_RELOC_PAGE21
-		// if r.Xadd is non-zero, add two MACHO_ARM64_RELOC_ADDEND.
-		if r.Xadd != 0 {
-			out.Write32(uint32(sectoff + 4))
-			out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
-		}
-		out.Write32(uint32(sectoff + 4))
-		out.Write32(v | (ld.MACHO_ARM64_RELOC_PAGEOFF12 << 28) | (2 << 25))
-		if r.Xadd != 0 {
-			out.Write32(uint32(sectoff))
-			out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
-		}
-		v |= 1 << 24 // pc-relative bit
-		v |= ld.MACHO_ARM64_RELOC_PAGE21 << 28
-	}
-
-	switch r.Siz {
-	default:
-		return false
-	case 1:
-		v |= 0 << 25
-	case 2:
-		v |= 1 << 25
-	case 4:
-		v |= 2 << 25
-	case 8:
-		v |= 3 << 25
-	}
-
-	out.Write32(uint32(sectoff))
-	out.Write32(v)
-	return true
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-	if ctxt.LinkMode == ld.LinkExternal {
-		switch r.Type {
-		default:
-			return val, false
-		case objabi.R_ARM64_GOTPCREL:
-			var o1, o2 uint32
-			if ctxt.Arch.ByteOrder == binary.BigEndian {
-				o1 = uint32(val >> 32)
-				o2 = uint32(val)
-			} else {
-				o1 = uint32(val)
-				o2 = uint32(val >> 32)
-			}
-			// Any relocation against a function symbol is redirected to
-			// be against a local symbol instead (see putelfsym in
-			// symtab.go) but unfortunately the system linker was buggy
-			// when confronted with a R_AARCH64_ADR_GOT_PAGE relocation
-			// against a local symbol until May 2015
-			// (https://sourceware.org/bugzilla/show_bug.cgi?id=18270). So
-			// we convert the adrp; ld64 + R_ARM64_GOTPCREL into adrp;
-			// add + R_ADDRARM64.
-			if !(r.Sym.IsFileLocal() || r.Sym.Attr.VisibilityHidden() || r.Sym.Attr.Local()) && r.Sym.Type == sym.STEXT && ctxt.DynlinkingGo() {
-				if o2&0xffc00000 != 0xf9400000 {
-					ld.Errorf(s, "R_ARM64_GOTPCREL against unexpected instruction %x", o2)
-				}
-				o2 = 0x91000000 | (o2 & 0x000003ff)
-				r.Type = objabi.R_ADDRARM64
-			}
-			if ctxt.Arch.ByteOrder == binary.BigEndian {
-				val = int64(o1)<<32 | int64(o2)
-			} else {
-				val = int64(o2)<<32 | int64(o1)
-			}
-			fallthrough
-		case objabi.R_ADDRARM64:
-			r.Done = false
-
-			// set up addend for eventual relocation via outer symbol.
-			rs := r.Sym
-			r.Xadd = r.Add
-			for rs.Outer != nil {
-				r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
-				rs = rs.Outer
-			}
-
-			if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
-				ld.Errorf(s, "missing section for %s", rs.Name)
-			}
-			r.Xsym = rs
-
-			// Note: ld64 currently has a bug that any non-zero addend for BR26 relocation
-			// will make the linking fail because it thinks the code is not PIC even though
-			// the BR26 relocation should be fully resolved at link time.
-			// That is the reason why the next if block is disabled. When the bug in ld64
-			// is fixed, we can enable this block and also enable duff's device in cmd/7g.
-			if false && ctxt.HeadType == objabi.Hdarwin {
-				var o0, o1 uint32
-
-				if ctxt.Arch.ByteOrder == binary.BigEndian {
-					o0 = uint32(val >> 32)
-					o1 = uint32(val)
-				} else {
-					o0 = uint32(val)
-					o1 = uint32(val >> 32)
-				}
-				// Mach-O wants the addend to be encoded in the instruction
-				// Note that although Mach-O supports ARM64_RELOC_ADDEND, it
-				// can only encode 24-bit of signed addend, but the instructions
-				// supports 33-bit of signed addend, so we always encode the
-				// addend in place.
-				o0 |= (uint32((r.Xadd>>12)&3) << 29) | (uint32((r.Xadd>>12>>2)&0x7ffff) << 5)
-				o1 |= uint32(r.Xadd&0xfff) << 10
-				r.Xadd = 0
-
-				// when laid out, the instruction order must always be o1, o2.
-				if ctxt.Arch.ByteOrder == binary.BigEndian {
-					val = int64(o0)<<32 | int64(o1)
-				} else {
-					val = int64(o1)<<32 | int64(o0)
-				}
-			}
-
-			return val, true
-		case objabi.R_CALLARM64,
-			objabi.R_ARM64_TLS_LE,
-			objabi.R_ARM64_TLS_IE:
-			r.Done = false
-			r.Xsym = r.Sym
-			r.Xadd = r.Add
-			return val, true
-		}
-	}
-
-	switch r.Type {
-	case objabi.R_CONST:
-		return r.Add, true
-
-	case objabi.R_GOTOFF:
-		return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
-
-	case objabi.R_ADDRARM64:
-		t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-		if t >= 1<<32 || t < -1<<32 {
-			ld.Errorf(s, "program too large, address relocation distance = %d", t)
-		}
-
-		var o0, o1 uint32
-
-		if ctxt.Arch.ByteOrder == binary.BigEndian {
-			o0 = uint32(val >> 32)
-			o1 = uint32(val)
-		} else {
-			o0 = uint32(val)
-			o1 = uint32(val >> 32)
-		}
-
-		o0 |= (uint32((t>>12)&3) << 29) | (uint32((t>>12>>2)&0x7ffff) << 5)
-		o1 |= uint32(t&0xfff) << 10
-
-		// when laid out, the instruction order must always be o1, o2.
-		if ctxt.Arch.ByteOrder == binary.BigEndian {
-			return int64(o0)<<32 | int64(o1), true
-		}
-		return int64(o1)<<32 | int64(o0), true
-
-	case objabi.R_ARM64_TLS_LE:
-		r.Done = false
-		if ctxt.HeadType == objabi.Hdarwin {
-			ld.Errorf(s, "TLS reloc on unsupported OS %v", ctxt.HeadType)
-		}
-		// The TCB is two pointers. This is not documented anywhere, but is
-		// de facto part of the ABI.
-		v := r.Sym.Value + int64(2*ctxt.Arch.PtrSize)
-		if v < 0 || v >= 32678 {
-			ld.Errorf(s, "TLS offset out of range %d", v)
-		}
-		return val | (v << 5), true
-
-	case objabi.R_ARM64_TLS_IE:
-		if ctxt.BuildMode == ld.BuildModePIE && ctxt.IsELF {
-			// We are linking the final executable, so we
-			// can optimize any TLS IE relocation to LE.
-			r.Done = false
-			if ctxt.HeadType != objabi.Hlinux {
-				ld.Errorf(s, "TLS reloc on unsupported OS %v", ctxt.HeadType)
-			}
-
-			// The TCB is two pointers. This is not documented anywhere, but is
-			// de facto part of the ABI.
-			v := ld.Symaddr(r.Sym) + int64(2*ctxt.Arch.PtrSize) + r.Add
-			if v < 0 || v >= 32678 {
-				ld.Errorf(s, "TLS offset out of range %d", v)
-			}
-
-			var o0, o1 uint32
-			if ctxt.Arch.ByteOrder == binary.BigEndian {
-				o0 = uint32(val >> 32)
-				o1 = uint32(val)
-			} else {
-				o0 = uint32(val)
-				o1 = uint32(val >> 32)
-			}
-
-			// R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
-			// turn ADRP to MOVZ
-			o0 = 0xd2a00000 | uint32(o0&0x1f) | (uint32((v>>16)&0xffff) << 5)
-			// R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
-			// turn LD64 to MOVK
-			if v&3 != 0 {
-				ld.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC", v)
-			}
-			o1 = 0xf2800000 | uint32(o1&0x1f) | (uint32(v&0xffff) << 5)
-
-			// when laid out, the instruction order must always be o0, o1.
-			if ctxt.Arch.ByteOrder == binary.BigEndian {
-				return int64(o0)<<32 | int64(o1), true
-			}
-			return int64(o1)<<32 | int64(o0), true
-		} else {
-			log.Fatalf("cannot handle R_ARM64_TLS_IE (sym %s) when linking internally", s.Name)
-		}
-
-	case objabi.R_CALLARM64:
-		var t int64
-		if r.Sym.Type == sym.SDYNIMPORT {
-			t = (ld.Symaddr(ctxt.Syms.Lookup(".plt", 0)) + r.Add) - (s.Value + int64(r.Off))
-		} else {
-			t = (ld.Symaddr(r.Sym) + r.Add) - (s.Value + int64(r.Off))
-		}
-		if t >= 1<<27 || t < -1<<27 {
-			ld.Errorf(s, "program too large, call relocation distance = %d", t)
-		}
-		return val | ((t >> 2) & 0x03ffffff), true
-
-	case objabi.R_ARM64_GOT:
-		if s.P[r.Off+3]&0x9f == 0x90 {
-			// R_AARCH64_ADR_GOT_PAGE
-			// patch instruction: adrp
-			t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-			if t >= 1<<32 || t < -1<<32 {
-				ld.Errorf(s, "program too large, address relocation distance = %d", t)
-			}
-			var o0 uint32
-			o0 |= (uint32((t>>12)&3) << 29) | (uint32((t>>12>>2)&0x7ffff) << 5)
-			return val | int64(o0), true
-		} else if s.P[r.Off+3] == 0xf9 {
-			// R_AARCH64_LD64_GOT_LO12_NC
-			// patch instruction: ldr
-			t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-			if t&7 != 0 {
-				ld.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_LD64_GOT_LO12_NC", t)
-			}
-			var o1 uint32
-			o1 |= uint32(t&0xfff) << (10 - 3)
-			return val | int64(uint64(o1)), true
-		} else {
-			ld.Errorf(s, "unsupported instruction for %v R_GOTARM64", s.P[r.Off:r.Off+4])
-		}
-
-	case objabi.R_ARM64_PCREL:
-		if s.P[r.Off+3]&0x9f == 0x90 {
-			// R_AARCH64_ADR_PREL_PG_HI21
-			// patch instruction: adrp
-			t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-			if t >= 1<<32 || t < -1<<32 {
-				ld.Errorf(s, "program too large, address relocation distance = %d", t)
-			}
-			o0 := (uint32((t>>12)&3) << 29) | (uint32((t>>12>>2)&0x7ffff) << 5)
-			return val | int64(o0), true
-		} else if s.P[r.Off+3]&0x91 == 0x91 {
-			// R_AARCH64_ADD_ABS_LO12_NC
-			// patch instruction: add
-			t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-			o1 := uint32(t&0xfff) << 10
-			return val | int64(o1), true
-		} else {
-			ld.Errorf(s, "unsupported instruction for %v R_PCRELARM64", s.P[r.Off:r.Off+4])
-		}
-
-	case objabi.R_ARM64_LDST8:
-		t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-		o0 := uint32(t&0xfff) << 10
-		return val | int64(o0), true
-
-	case objabi.R_ARM64_LDST32:
-		t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-		if t&3 != 0 {
-			ld.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_LDST32_ABS_LO12_NC", t)
-		}
-		o0 := (uint32(t&0xfff) >> 2) << 10
-		return val | int64(o0), true
-
-	case objabi.R_ARM64_LDST64:
-		t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-		if t&7 != 0 {
-			ld.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_LDST64_ABS_LO12_NC", t)
-		}
-		o0 := (uint32(t&0xfff) >> 3) << 10
-		return val | int64(o0), true
-
-	case objabi.R_ARM64_LDST128:
-		t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-		if t&15 != 0 {
-			ld.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_LDST128_ABS_LO12_NC", t)
-		}
-		o0 := (uint32(t&0xfff) >> 4) << 10
-		return val | int64(o0), true
-	}
-
-	return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-	log.Fatalf("unexpected relocation variant")
-	return -1
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-	plt := ctxt.Syms.Lookup(".plt", 0)
-	gotplt := ctxt.Syms.Lookup(".got.plt", 0)
-	if plt.Size == 0 {
-		// stp     x16, x30, [sp, #-16]!
-		// identifying information
-		plt.AddUint32(ctxt.Arch, 0xa9bf7bf0)
-
-		// the following two instructions (adrp + ldr) load *got[2] into x17
-		// adrp    x16, &got[0]
-		plt.AddAddrPlus4(gotplt, 16)
-		plt.SetUint32(ctxt.Arch, plt.Size-4, 0x90000010)
-		plt.R[len(plt.R)-1].Type = objabi.R_ARM64_GOT
-
-		// <imm> is the offset value of &got[2] to &got[0], the same below
-		// ldr     x17, [x16, <imm>]
-		plt.AddAddrPlus4(gotplt, 16)
-		plt.SetUint32(ctxt.Arch, plt.Size-4, 0xf9400211)
-		plt.R[len(plt.R)-1].Type = objabi.R_ARM64_GOT
-
-		// add     x16, x16, <imm>
-		plt.AddAddrPlus4(gotplt, 16)
-		plt.SetUint32(ctxt.Arch, plt.Size-4, 0x91000210)
-		plt.R[len(plt.R)-1].Type = objabi.R_ARM64_PCREL
-
-		// br      x17
-		plt.AddUint32(ctxt.Arch, 0xd61f0220)
-
-		// 3 nop for place holder
-		plt.AddUint32(ctxt.Arch, 0xd503201f)
-		plt.AddUint32(ctxt.Arch, 0xd503201f)
-		plt.AddUint32(ctxt.Arch, 0xd503201f)
-
-		// check gotplt.size == 0
-		if gotplt.Size != 0 {
-			ld.Errorf(gotplt, "got.plt is not empty at the very beginning")
-		}
-		gotplt.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
-
-		gotplt.AddUint64(ctxt.Arch, 0)
-		gotplt.AddUint64(ctxt.Arch, 0)
-	}
-}
-
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
-	if s.Plt() >= 0 {
-		return
-	}
-
-	ld.Adddynsym(ctxt, s)
-
-	if ctxt.IsELF {
-		plt := ctxt.Syms.Lookup(".plt", 0)
-		gotplt := ctxt.Syms.Lookup(".got.plt", 0)
-		rela := ctxt.Syms.Lookup(".rela.plt", 0)
-		if plt.Size == 0 {
-			elfsetupplt(ctxt)
-		}
-
-		// adrp    x16, &got.plt[0]
-		plt.AddAddrPlus4(gotplt, gotplt.Size)
-		plt.SetUint32(ctxt.Arch, plt.Size-4, 0x90000010)
-		plt.R[len(plt.R)-1].Type = objabi.R_ARM64_GOT
-
-		// <offset> is the offset value of &got.plt[n] to &got.plt[0]
-		// ldr     x17, [x16, <offset>]
-		plt.AddAddrPlus4(gotplt, gotplt.Size)
-		plt.SetUint32(ctxt.Arch, plt.Size-4, 0xf9400211)
-		plt.R[len(plt.R)-1].Type = objabi.R_ARM64_GOT
-
-		// add     x16, x16, <offset>
-		plt.AddAddrPlus4(gotplt, gotplt.Size)
-		plt.SetUint32(ctxt.Arch, plt.Size-4, 0x91000210)
-		plt.R[len(plt.R)-1].Type = objabi.R_ARM64_PCREL
-
-		// br      x17
-		plt.AddUint32(ctxt.Arch, 0xd61f0220)
-
-		// add to got.plt: pointer to plt[0]
-		gotplt.AddAddrPlus(ctxt.Arch, plt, 0)
-
-		// rela
-		rela.AddAddrPlus(ctxt.Arch, gotplt, gotplt.Size-8)
-		rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_AARCH64_JUMP_SLOT)))
-		rela.AddUint64(ctxt.Arch, 0)
-
-		s.SetPlt(int32(plt.Size - 16))
-	} else {
-		ld.Errorf(s, "addpltsym: unsupported binary format")
-	}
-}
-
-func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
-	if s.Got() >= 0 {
-		return
-	}
-
-	ld.Adddynsym(ctxt, s)
-	got := ctxt.Syms.Lookup(".got", 0)
-	s.SetGot(int32(got.Size))
-	got.AddUint64(ctxt.Arch, 0)
-
-	if ctxt.IsELF {
-		rela := ctxt.Syms.Lookup(".rela", 0)
-		rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
-		rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_AARCH64_GLOB_DAT)))
-		rela.AddUint64(ctxt.Arch, 0)
-	} else {
-		ld.Errorf(s, "addgotsym: unsupported binary format")
-	}
-}
-
-func asmb(ctxt *ld.Link) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	sect := ld.Segtext.Sections[0]
-	ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-	ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-	for _, sect = range ld.Segtext.Sections[1:] {
-		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-		ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-	}
-	if ld.Segrelrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
-	}
-
-	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-	machlink := uint32(0)
-	if ctxt.HeadType == objabi.Hdarwin {
-		machlink = uint32(ld.Domacholink(ctxt))
-	}
-
-	/* output symbol table */
-	ld.Symsize = 0
-
-	ld.Lcsize = 0
-	symo := uint32(0)
-	if !*ld.FlagS {
-		// TODO: rationalize
-		switch ctxt.HeadType {
-		default:
-			if ctxt.IsELF {
-				symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-				symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
-			}
-
-		case objabi.Hplan9:
-			symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
-
-		case objabi.Hdarwin:
-			symo = uint32(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(*ld.FlagRound))) + uint64(machlink))
-		}
-
-		ctxt.Out.SeekSet(int64(symo))
-		switch ctxt.HeadType {
-		default:
-			if ctxt.IsELF {
-				ld.Asmelfsym(ctxt)
-				ctxt.Out.Flush()
-				ctxt.Out.Write(ld.Elfstrdat)
-
-				if ctxt.LinkMode == ld.LinkExternal {
-					ld.Elfemitreloc(ctxt)
-				}
-			}
-
-		case objabi.Hplan9:
-			ld.Asmplan9sym(ctxt)
-			ctxt.Out.Flush()
-
-			sym := ctxt.Syms.Lookup("pclntab", 0)
-			if sym != nil {
-				ld.Lcsize = int32(len(sym.P))
-				ctxt.Out.Write(sym.P)
-				ctxt.Out.Flush()
-			}
-
-		case objabi.Hdarwin:
-			if ctxt.LinkMode == ld.LinkExternal {
-				ld.Machoemitreloc(ctxt)
-			}
-		}
-	}
-
-	ctxt.Out.SeekSet(0)
-	switch ctxt.HeadType {
-	default:
-	case objabi.Hplan9: /* plan 9 */
-		ctxt.Out.Write32(0x647)                      /* magic */
-		ctxt.Out.Write32(uint32(ld.Segtext.Filelen)) /* sizes */
-		ctxt.Out.Write32(uint32(ld.Segdata.Filelen))
-		ctxt.Out.Write32(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-		ctxt.Out.Write32(uint32(ld.Symsize))          /* nsyms */
-		ctxt.Out.Write32(uint32(ld.Entryvalue(ctxt))) /* va of entry */
-		ctxt.Out.Write32(0)
-		ctxt.Out.Write32(uint32(ld.Lcsize))
-
-	case objabi.Hlinux,
-		objabi.Hfreebsd,
-		objabi.Hnetbsd,
-		objabi.Hopenbsd:
-		ld.Asmbelf(ctxt, int64(symo))
-
-	case objabi.Hdarwin:
-		ld.Asmbmacho(ctxt)
-	}
-
-	ctxt.Out.Flush()
-	if *ld.FlagC {
-		fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
-		fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
-		fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
-		fmt.Printf("symsize=%d\n", ld.Symsize)
-		fmt.Printf("lcsize=%d\n", ld.Lcsize)
-		fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
-	}
-}
diff --git a/src/cmd/oldlink/internal/arm64/l.go b/src/cmd/oldlink/internal/arm64/l.go
deleted file mode 100644
index 5f35303..0000000
--- a/src/cmd/oldlink/internal/arm64/l.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package arm64
-
-// Writing object files.
-
-// cmd/9l/l.h from Vita Nuova.
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-const (
-	maxAlign  = 32 // max data alignment
-	minAlign  = 1  // min data alignment
-	funcAlign = 16
-)
-
-/* Used by ../internal/ld/dwarf.go */
-const (
-	dwarfRegSP = 31
-	dwarfRegLR = 30
-)
diff --git a/src/cmd/oldlink/internal/arm64/obj.go b/src/cmd/oldlink/internal/arm64/obj.go
deleted file mode 100644
index 2dcc999..0000000
--- a/src/cmd/oldlink/internal/arm64/obj.go
+++ /dev/null
@@ -1,110 +0,0 @@
-// Inferno utils/5l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/obj.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package arm64
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-	arch := sys.ArchARM64
-
-	theArch := ld.Arch{
-		Funcalign:  funcAlign,
-		Maxalign:   maxAlign,
-		Minalign:   minAlign,
-		Dwarfregsp: dwarfRegSP,
-		Dwarfreglr: dwarfRegLR,
-
-		Adddynrel:        adddynrel,
-		Archinit:         archinit,
-		Archreloc:        archreloc,
-		Archrelocvariant: archrelocvariant,
-		Asmb:             asmb,
-		Asmb2:            asmb2,
-		Elfreloc1:        elfreloc1,
-		Elfsetupplt:      elfsetupplt,
-		Gentext:          gentext,
-		Machoreloc1:      machoreloc1,
-
-		Androiddynld: "/system/bin/linker64",
-		Linuxdynld:   "/lib/ld-linux-aarch64.so.1",
-
-		Freebsddynld:   "/usr/libexec/ld-elf.so.1",
-		Openbsddynld:   "/usr/libexec/ld.so",
-		Netbsddynld:    "/libexec/ld.elf_so",
-		Dragonflydynld: "XXX",
-		Solarisdynld:   "XXX",
-	}
-
-	return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-	switch ctxt.HeadType {
-	default:
-		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-
-	case objabi.Hplan9: /* plan 9 */
-		ld.HEADR = 32
-
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 4096 + int64(ld.HEADR)
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 4096
-		}
-
-	case objabi.Hlinux, /* arm64 elf */
-		objabi.Hfreebsd,
-		objabi.Hnetbsd,
-		objabi.Hopenbsd:
-		ld.Elfinit(ctxt)
-		ld.HEADR = ld.ELFRESERVE
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 0x10000
-		}
-
-	case objabi.Hdarwin: /* apple MACH */
-		ld.HEADR = ld.INITIAL_MACHO_HEADR
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 4096 + int64(ld.HEADR)
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 4096
-		}
-	}
-}
diff --git a/src/cmd/oldlink/internal/ld/ar.go b/src/cmd/oldlink/internal/ld/ar.go
deleted file mode 100644
index 8df859f..0000000
--- a/src/cmd/oldlink/internal/ld/ar.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Inferno utils/include/ar.h
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/include/ar.h
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ld
-
-import (
-	"cmd/internal/bio"
-	"cmd/internal/objabi"
-	"cmd/oldlink/internal/sym"
-	"encoding/binary"
-	"fmt"
-	"io"
-	"os"
-)
-
-const (
-	SARMAG  = 8
-	SAR_HDR = 16 + 44
-)
-
-const (
-	ARMAG = "!<arch>\n"
-)
-
-type ArHdr struct {
-	name string
-	date string
-	uid  string
-	gid  string
-	mode string
-	size string
-	fmag string
-}
-
-// hostArchive reads an archive file holding host objects and links in
-// required objects. The general format is the same as a Go archive
-// file, but it has an armap listing symbols and the objects that
-// define them. This is used for the compiler support library
-// libgcc.a.
-func hostArchive(ctxt *Link, name string) {
-	f, err := bio.Open(name)
-	if err != nil {
-		if os.IsNotExist(err) {
-			// It's OK if we don't have a libgcc file at all.
-			if ctxt.Debugvlog != 0 {
-				ctxt.Logf("skipping libgcc file: %v\n", err)
-			}
-			return
-		}
-		Exitf("cannot open file %s: %v", name, err)
-	}
-	defer f.Close()
-
-	var magbuf [len(ARMAG)]byte
-	if _, err := io.ReadFull(f, magbuf[:]); err != nil {
-		Exitf("file %s too short", name)
-	}
-
-	if string(magbuf[:]) != ARMAG {
-		Exitf("%s is not an archive file", name)
-	}
-
-	var arhdr ArHdr
-	l := nextar(f, f.Offset(), &arhdr)
-	if l <= 0 {
-		Exitf("%s missing armap", name)
-	}
-
-	var armap archiveMap
-	if arhdr.name == "/" || arhdr.name == "/SYM64/" {
-		armap = readArmap(name, f, arhdr)
-	} else {
-		Exitf("%s missing armap", name)
-	}
-
-	loaded := make(map[uint64]bool)
-	any := true
-	for any {
-		var load []uint64
-		for _, s := range ctxt.Syms.Allsym {
-			for i := range s.R {
-				r := &s.R[i] // Copying sym.Reloc has measurable impact on performance
-				if r.Sym != nil && r.Sym.Type == sym.SXREF {
-					if off := armap[r.Sym.Name]; off != 0 && !loaded[off] {
-						load = append(load, off)
-						loaded[off] = true
-					}
-				}
-			}
-		}
-
-		for _, off := range load {
-			l := nextar(f, int64(off), &arhdr)
-			if l <= 0 {
-				Exitf("%s missing archive entry at offset %d", name, off)
-			}
-			pname := fmt.Sprintf("%s(%s)", name, arhdr.name)
-			l = atolwhex(arhdr.size)
-
-			libgcc := sym.Library{Pkg: "libgcc"}
-			h := ldobj(ctxt, f, &libgcc, l, pname, name)
-			f.MustSeek(h.off, 0)
-			h.ld(ctxt, f, h.pkg, h.length, h.pn)
-		}
-
-		any = len(load) > 0
-	}
-}
-
-// archiveMap is an archive symbol map: a mapping from symbol name to
-// offset within the archive file.
-type archiveMap map[string]uint64
-
-// readArmap reads the archive symbol map.
-func readArmap(filename string, f *bio.Reader, arhdr ArHdr) archiveMap {
-	is64 := arhdr.name == "/SYM64/"
-	wordSize := 4
-	if is64 {
-		wordSize = 8
-	}
-
-	contents := make([]byte, atolwhex(arhdr.size))
-	if _, err := io.ReadFull(f, contents); err != nil {
-		Exitf("short read from %s", filename)
-	}
-
-	var c uint64
-	if is64 {
-		c = binary.BigEndian.Uint64(contents)
-	} else {
-		c = uint64(binary.BigEndian.Uint32(contents))
-	}
-	contents = contents[wordSize:]
-
-	ret := make(archiveMap)
-
-	names := contents[c*uint64(wordSize):]
-	for i := uint64(0); i < c; i++ {
-		n := 0
-		for names[n] != 0 {
-			n++
-		}
-		name := string(names[:n])
-		names = names[n+1:]
-
-		// For Mach-O and PE/386 files we strip a leading
-		// underscore from the symbol name.
-		if objabi.GOOS == "darwin" || (objabi.GOOS == "windows" && objabi.GOARCH == "386") {
-			if name[0] == '_' && len(name) > 1 {
-				name = name[1:]
-			}
-		}
-
-		var off uint64
-		if is64 {
-			off = binary.BigEndian.Uint64(contents)
-		} else {
-			off = uint64(binary.BigEndian.Uint32(contents))
-		}
-		contents = contents[wordSize:]
-
-		ret[name] = off
-	}
-
-	return ret
-}
diff --git a/src/cmd/oldlink/internal/ld/config.go b/src/cmd/oldlink/internal/ld/config.go
deleted file mode 100644
index 2373b50..0000000
--- a/src/cmd/oldlink/internal/ld/config.go
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ld
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"fmt"
-	"log"
-)
-
-// A BuildMode indicates the sort of object we are building.
-//
-// Possible build modes are the same as those for the -buildmode flag
-// in cmd/go, and are documented in 'go help buildmode'.
-type BuildMode uint8
-
-const (
-	BuildModeUnset BuildMode = iota
-	BuildModeExe
-	BuildModePIE
-	BuildModeCArchive
-	BuildModeCShared
-	BuildModeShared
-	BuildModePlugin
-)
-
-func (mode *BuildMode) Set(s string) error {
-	badmode := func() error {
-		return fmt.Errorf("buildmode %s not supported on %s/%s", s, objabi.GOOS, objabi.GOARCH)
-	}
-	switch s {
-	default:
-		return fmt.Errorf("invalid buildmode: %q", s)
-	case "exe":
-		*mode = BuildModeExe
-	case "pie":
-		switch objabi.GOOS {
-		case "aix", "android", "linux", "windows":
-		case "darwin", "freebsd":
-			switch objabi.GOARCH {
-			case "amd64":
-			default:
-				return badmode()
-			}
-		default:
-			return badmode()
-		}
-		*mode = BuildModePIE
-	case "c-archive":
-		switch objabi.GOOS {
-		case "aix", "darwin", "linux":
-		case "freebsd":
-			switch objabi.GOARCH {
-			case "amd64":
-			default:
-				return badmode()
-			}
-		case "windows":
-			switch objabi.GOARCH {
-			case "amd64", "386", "arm":
-			default:
-				return badmode()
-			}
-		default:
-			return badmode()
-		}
-		*mode = BuildModeCArchive
-	case "c-shared":
-		switch objabi.GOARCH {
-		case "386", "amd64", "arm", "arm64", "ppc64le", "s390x":
-		default:
-			return badmode()
-		}
-		*mode = BuildModeCShared
-	case "shared":
-		switch objabi.GOOS {
-		case "linux":
-			switch objabi.GOARCH {
-			case "386", "amd64", "arm", "arm64", "ppc64le", "s390x":
-			default:
-				return badmode()
-			}
-		default:
-			return badmode()
-		}
-		*mode = BuildModeShared
-	case "plugin":
-		switch objabi.GOOS {
-		case "linux":
-			switch objabi.GOARCH {
-			case "386", "amd64", "arm", "arm64", "s390x", "ppc64le":
-			default:
-				return badmode()
-			}
-		case "darwin", "freebsd":
-			switch objabi.GOARCH {
-			case "amd64":
-			default:
-				return badmode()
-			}
-		default:
-			return badmode()
-		}
-		*mode = BuildModePlugin
-	}
-	return nil
-}
-
-func (mode *BuildMode) String() string {
-	switch *mode {
-	case BuildModeUnset:
-		return "" // avoid showing a default in usage message
-	case BuildModeExe:
-		return "exe"
-	case BuildModePIE:
-		return "pie"
-	case BuildModeCArchive:
-		return "c-archive"
-	case BuildModeCShared:
-		return "c-shared"
-	case BuildModeShared:
-		return "shared"
-	case BuildModePlugin:
-		return "plugin"
-	}
-	return fmt.Sprintf("BuildMode(%d)", uint8(*mode))
-}
-
-// LinkMode indicates whether an external linker is used for the final link.
-type LinkMode uint8
-
-const (
-	LinkAuto LinkMode = iota
-	LinkInternal
-	LinkExternal
-)
-
-func (mode *LinkMode) Set(s string) error {
-	switch s {
-	default:
-		return fmt.Errorf("invalid linkmode: %q", s)
-	case "auto":
-		*mode = LinkAuto
-	case "internal":
-		*mode = LinkInternal
-	case "external":
-		*mode = LinkExternal
-	}
-	return nil
-}
-
-func (mode *LinkMode) String() string {
-	switch *mode {
-	case LinkAuto:
-		return "auto"
-	case LinkInternal:
-		return "internal"
-	case LinkExternal:
-		return "external"
-	}
-	return fmt.Sprintf("LinkMode(%d)", uint8(*mode))
-}
-
-// mustLinkExternal reports whether the program being linked requires
-// the external linker be used to complete the link.
-func mustLinkExternal(ctxt *Link) (res bool, reason string) {
-	if ctxt.Debugvlog > 1 {
-		defer func() {
-			if res {
-				log.Printf("external linking is forced by: %s\n", reason)
-			}
-		}()
-	}
-
-	if sys.MustLinkExternal(objabi.GOOS, objabi.GOARCH) {
-		return true, fmt.Sprintf("%s/%s requires external linking", objabi.GOOS, objabi.GOARCH)
-	}
-
-	if *flagMsan {
-		return true, "msan"
-	}
-
-	// Internally linking cgo is incomplete on some architectures.
-	// https://golang.org/issue/14449
-	// https://golang.org/issue/21961
-	if iscgo && ctxt.Arch.InFamily(sys.MIPS64, sys.MIPS, sys.PPC64) {
-		return true, objabi.GOARCH + " does not support internal cgo"
-	}
-	if iscgo && objabi.GOOS == "android" {
-		return true, objabi.GOOS + " does not support internal cgo"
-	}
-
-	// When the race flag is set, the LLVM tsan relocatable file is linked
-	// into the final binary, which means external linking is required because
-	// internal linking does not support it.
-	if *flagRace && ctxt.Arch.InFamily(sys.PPC64) {
-		return true, "race on " + objabi.GOARCH
-	}
-
-	// Some build modes require work the internal linker cannot do (yet).
-	switch ctxt.BuildMode {
-	case BuildModeCArchive:
-		return true, "buildmode=c-archive"
-	case BuildModeCShared:
-		return true, "buildmode=c-shared"
-	case BuildModePIE:
-		switch objabi.GOOS + "/" + objabi.GOARCH {
-		case "linux/amd64", "linux/arm64", "android/arm64":
-		case "windows/386", "windows/amd64", "windows/arm":
-		default:
-			// Internal linking does not support TLS_IE.
-			return true, "buildmode=pie"
-		}
-	case BuildModePlugin:
-		return true, "buildmode=plugin"
-	case BuildModeShared:
-		return true, "buildmode=shared"
-	}
-	if ctxt.linkShared {
-		return true, "dynamically linking with a shared library"
-	}
-
-	return false, ""
-}
-
-// determineLinkMode sets ctxt.LinkMode.
-//
-// It is called after flags are processed and inputs are processed,
-// so the ctxt.LinkMode variable has an initial value from the -linkmode
-// flag and the iscgo externalobj variables are set.
-func determineLinkMode(ctxt *Link) {
-	extNeeded, extReason := mustLinkExternal(ctxt)
-	via := ""
-
-	if ctxt.LinkMode == LinkAuto {
-		// The environment variable GO_EXTLINK_ENABLED controls the
-		// default value of -linkmode. If it is not set when the
-		// linker is called we take the value it was set to when
-		// cmd/link was compiled. (See make.bash.)
-		switch objabi.Getgoextlinkenabled() {
-		case "0":
-			ctxt.LinkMode = LinkInternal
-			via = "via GO_EXTLINK_ENABLED "
-		case "1":
-			ctxt.LinkMode = LinkExternal
-			via = "via GO_EXTLINK_ENABLED "
-		default:
-			if extNeeded || (iscgo && externalobj) {
-				ctxt.LinkMode = LinkExternal
-			} else {
-				ctxt.LinkMode = LinkInternal
-			}
-		}
-	}
-
-	switch ctxt.LinkMode {
-	case LinkInternal:
-		if extNeeded {
-			Exitf("internal linking requested %sbut external linking required: %s", via, extReason)
-		}
-	case LinkExternal:
-		switch {
-		case objabi.GOARCH == "riscv64":
-			Exitf("external linking not supported for %s/riscv64", objabi.GOOS)
-		case objabi.GOARCH == "ppc64" && objabi.GOOS != "aix":
-			Exitf("external linking not supported for %s/ppc64", objabi.GOOS)
-		}
-	}
-}
diff --git a/src/cmd/oldlink/internal/ld/data.go b/src/cmd/oldlink/internal/ld/data.go
deleted file mode 100644
index ba4a741..0000000
--- a/src/cmd/oldlink/internal/ld/data.go
+++ /dev/null
@@ -1,2501 +0,0 @@
-// Derived from Inferno utils/6l/obj.c and utils/6l/span.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ld
-
-import (
-	"bufio"
-	"bytes"
-	"cmd/internal/gcprog"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/sym"
-	"compress/zlib"
-	"encoding/binary"
-	"fmt"
-	"log"
-	"os"
-	"sort"
-	"strconv"
-	"strings"
-	"sync"
-)
-
-// isRuntimeDepPkg reports whether pkg is the runtime package or its dependency
-func isRuntimeDepPkg(pkg string) bool {
-	switch pkg {
-	case "runtime",
-		"sync/atomic",      // runtime may call to sync/atomic, due to go:linkname
-		"internal/bytealg", // for IndexByte
-		"internal/cpu":     // for cpu features
-		return true
-	}
-	return strings.HasPrefix(pkg, "runtime/internal/") && !strings.HasSuffix(pkg, "_test")
-}
-
-// Estimate the max size needed to hold any new trampolines created for this function. This
-// is used to determine when the section can be split if it becomes too large, to ensure that
-// the trampolines are in the same section as the function that uses them.
-func maxSizeTrampolinesPPC64(s *sym.Symbol, isTramp bool) uint64 {
-	// If thearch.Trampoline is nil, then trampoline support is not available on this arch.
-	// A trampoline does not need any dependent trampolines.
-	if thearch.Trampoline == nil || isTramp {
-		return 0
-	}
-
-	n := uint64(0)
-	for ri := range s.R {
-		r := &s.R[ri]
-		if r.Type.IsDirectCallOrJump() {
-			n++
-		}
-	}
-	// Trampolines in ppc64 are 4 instructions.
-	return n * 16
-}
-
-// detect too-far jumps in function s, and add trampolines if necessary
-// ARM, PPC64 & PPC64LE support trampoline insertion for internal and external linking
-// On PPC64 & PPC64LE the text sections might be split but will still insert trampolines
-// where necessary.
-func trampoline(ctxt *Link, s *sym.Symbol) {
-	if thearch.Trampoline == nil {
-		return // no need or no support of trampolines on this arch
-	}
-
-	for ri := range s.R {
-		r := &s.R[ri]
-		if !r.Type.IsDirectCallOrJump() {
-			continue
-		}
-		if Symaddr(r.Sym) == 0 && (r.Sym.Type != sym.SDYNIMPORT && r.Sym.Type != sym.SUNDEFEXT) {
-			if r.Sym.File != s.File {
-				if !isRuntimeDepPkg(s.File) || !isRuntimeDepPkg(r.Sym.File) {
-					ctxt.ErrorUnresolved(s, r)
-				}
-				// runtime and its dependent packages may call to each other.
-				// they are fine, as they will be laid down together.
-			}
-			continue
-		}
-
-		thearch.Trampoline(ctxt, r, s)
-	}
-
-}
-
-// relocsym resolve relocations in "s". The main loop walks through
-// the list of relocations attached to "s" and resolves them where
-// applicable. Relocations are often architecture-specific, requiring
-// calls into the 'archreloc' and/or 'archrelocvariant' functions for
-// the architecture. When external linking is in effect, it may not be
-// possible to completely resolve the address/offset for a symbol, in
-// which case the goal is to lay the groundwork for turning a given
-// relocation into an external reloc (to be applied by the external
-// linker). For more on how relocations work in general, see
-//
-//  "Linkers and Loaders", by John R. Levine (Morgan Kaufmann, 1999), ch. 7
-//
-// This is a performance-critical function for the linker; be careful
-// to avoid introducing unnecessary allocations in the main loop.
-func relocsym(ctxt *Link, s *sym.Symbol) {
-	if len(s.R) == 0 {
-		return
-	}
-	if s.Attr.ReadOnly() {
-		// The symbol's content is backed by read-only memory.
-		// Copy it to writable memory to apply relocations.
-		s.P = append([]byte(nil), s.P...)
-		s.Attr.Set(sym.AttrReadOnly, false)
-	}
-	for ri := int32(0); ri < int32(len(s.R)); ri++ {
-		r := &s.R[ri]
-		if r.Done {
-			// Relocation already processed by an earlier phase.
-			continue
-		}
-		r.Done = true
-		off := r.Off
-		siz := int32(r.Siz)
-		if off < 0 || off+siz > int32(len(s.P)) {
-			rname := ""
-			if r.Sym != nil {
-				rname = r.Sym.Name
-			}
-			Errorf(s, "invalid relocation %s: %d+%d not in [%d,%d)", rname, off, siz, 0, len(s.P))
-			continue
-		}
-
-		if r.Sym != nil && ((r.Sym.Type == sym.Sxxx && !r.Sym.Attr.VisibilityHidden()) || r.Sym.Type == sym.SXREF) {
-			// When putting the runtime but not main into a shared library
-			// these symbols are undefined and that's OK.
-			if ctxt.BuildMode == BuildModeShared || ctxt.BuildMode == BuildModePlugin {
-				if r.Sym.Name == "main.main" || (ctxt.BuildMode != BuildModePlugin && r.Sym.Name == "main..inittask") {
-					r.Sym.Type = sym.SDYNIMPORT
-				} else if strings.HasPrefix(r.Sym.Name, "go.info.") {
-					// Skip go.info symbols. They are only needed to communicate
-					// DWARF info between the compiler and linker.
-					continue
-				}
-			} else {
-				ctxt.ErrorUnresolved(s, r)
-				continue
-			}
-		}
-
-		if r.Type >= objabi.ElfRelocOffset {
-			continue
-		}
-		if r.Siz == 0 { // informational relocation - no work to do
-			continue
-		}
-
-		// We need to be able to reference dynimport symbols when linking against
-		// shared libraries, and Solaris, Darwin and AIX need it always
-		if ctxt.HeadType != objabi.Hsolaris && ctxt.HeadType != objabi.Hdarwin && ctxt.HeadType != objabi.Haix && r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT && !ctxt.DynlinkingGo() && !r.Sym.Attr.SubSymbol() {
-			if !(ctxt.Arch.Family == sys.PPC64 && ctxt.LinkMode == LinkExternal && r.Sym.Name == ".TOC.") {
-				Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", r.Sym.Name, r.Sym.Type, r.Sym.Type, r.Type, sym.RelocName(ctxt.Arch, r.Type))
-			}
-		}
-		if r.Sym != nil && r.Sym.Type != sym.STLSBSS && r.Type != objabi.R_WEAKADDROFF && !r.Sym.Attr.Reachable() {
-			Errorf(s, "unreachable sym in relocation: %s", r.Sym.Name)
-		}
-
-		if ctxt.LinkMode == LinkExternal {
-			r.InitExt()
-		}
-
-		// TODO(mundaym): remove this special case - see issue 14218.
-		if ctxt.Arch.Family == sys.S390X {
-			switch r.Type {
-			case objabi.R_PCRELDBL:
-				r.InitExt()
-				r.Type = objabi.R_PCREL
-				r.Variant = sym.RV_390_DBL
-			case objabi.R_CALL:
-				r.InitExt()
-				r.Variant = sym.RV_390_DBL
-			}
-		}
-
-		var o int64
-		switch r.Type {
-		default:
-			switch siz {
-			default:
-				Errorf(s, "bad reloc size %#x for %s", uint32(siz), r.Sym.Name)
-			case 1:
-				o = int64(s.P[off])
-			case 2:
-				o = int64(ctxt.Arch.ByteOrder.Uint16(s.P[off:]))
-			case 4:
-				o = int64(ctxt.Arch.ByteOrder.Uint32(s.P[off:]))
-			case 8:
-				o = int64(ctxt.Arch.ByteOrder.Uint64(s.P[off:]))
-			}
-			if offset, ok := thearch.Archreloc(ctxt, r, s, o); ok {
-				o = offset
-			} else {
-				Errorf(s, "unknown reloc to %v: %d (%s)", r.Sym.Name, r.Type, sym.RelocName(ctxt.Arch, r.Type))
-			}
-		case objabi.R_TLS_LE:
-			if ctxt.LinkMode == LinkExternal && ctxt.IsELF {
-				r.Done = false
-				if r.Sym == nil {
-					r.Sym = ctxt.Tlsg
-				}
-				r.Xsym = r.Sym
-				r.Xadd = r.Add
-				o = 0
-				if ctxt.Arch.Family != sys.AMD64 {
-					o = r.Add
-				}
-				break
-			}
-
-			if ctxt.IsELF && ctxt.Arch.Family == sys.ARM {
-				// On ELF ARM, the thread pointer is 8 bytes before
-				// the start of the thread-local data block, so add 8
-				// to the actual TLS offset (r->sym->value).
-				// This 8 seems to be a fundamental constant of
-				// ELF on ARM (or maybe Glibc on ARM); it is not
-				// related to the fact that our own TLS storage happens
-				// to take up 8 bytes.
-				o = 8 + r.Sym.Value
-			} else if ctxt.IsELF || ctxt.HeadType == objabi.Hplan9 || ctxt.HeadType == objabi.Hdarwin {
-				o = int64(ctxt.Tlsoffset) + r.Add
-			} else if ctxt.HeadType == objabi.Hwindows {
-				o = r.Add
-			} else {
-				log.Fatalf("unexpected R_TLS_LE relocation for %v", ctxt.HeadType)
-			}
-		case objabi.R_TLS_IE:
-			if ctxt.LinkMode == LinkExternal && ctxt.IsELF {
-				r.Done = false
-				if r.Sym == nil {
-					r.Sym = ctxt.Tlsg
-				}
-				r.Xsym = r.Sym
-				r.Xadd = r.Add
-				o = 0
-				if ctxt.Arch.Family != sys.AMD64 {
-					o = r.Add
-				}
-				break
-			}
-			if ctxt.BuildMode == BuildModePIE && ctxt.IsELF {
-				// We are linking the final executable, so we
-				// can optimize any TLS IE relocation to LE.
-				if thearch.TLSIEtoLE == nil {
-					log.Fatalf("internal linking of TLS IE not supported on %v", ctxt.Arch.Family)
-				}
-				thearch.TLSIEtoLE(s, int(off), int(r.Siz))
-				o = int64(ctxt.Tlsoffset)
-				// TODO: o += r.Add when ctxt.Arch.Family != sys.AMD64?
-				// Why do we treat r.Add differently on AMD64?
-				// Is the external linker using Xadd at all?
-			} else {
-				log.Fatalf("cannot handle R_TLS_IE (sym %s) when linking internally", s.Name)
-			}
-		case objabi.R_ADDR:
-			if ctxt.LinkMode == LinkExternal && r.Sym.Type != sym.SCONST {
-				r.Done = false
-
-				// set up addend for eventual relocation via outer symbol.
-				rs := r.Sym
-
-				r.Xadd = r.Add
-				for rs.Outer != nil {
-					r.Xadd += Symaddr(rs) - Symaddr(rs.Outer)
-					rs = rs.Outer
-				}
-
-				if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Type != sym.SUNDEFEXT && rs.Sect == nil {
-					Errorf(s, "missing section for relocation target %s", rs.Name)
-				}
-				r.Xsym = rs
-
-				o = r.Xadd
-				if ctxt.IsELF {
-					if ctxt.Arch.Family == sys.AMD64 {
-						o = 0
-					}
-				} else if ctxt.HeadType == objabi.Hdarwin {
-					if rs.Type != sym.SHOSTOBJ {
-						o += Symaddr(rs)
-					}
-				} else if ctxt.HeadType == objabi.Hwindows {
-					// nothing to do
-				} else if ctxt.HeadType == objabi.Haix {
-					o = Symaddr(r.Sym) + r.Add
-				} else {
-					Errorf(s, "unhandled pcrel relocation to %s on %v", rs.Name, ctxt.HeadType)
-				}
-
-				break
-			}
-
-			// On AIX, a second relocation must be done by the loader,
-			// as section addresses can change once loaded.
-			// The "default" symbol address is still needed by the loader so
-			// the current relocation can't be skipped.
-			if ctxt.HeadType == objabi.Haix && r.Sym.Type != sym.SDYNIMPORT {
-				// It's not possible to make a loader relocation in a
-				// symbol which is not inside .data section.
-				// FIXME: It should be forbidden to have R_ADDR from a
-				// symbol which isn't in .data. However, as .text has the
-				// same address once loaded, this is possible.
-				if s.Sect.Seg == &Segdata {
-					Xcoffadddynrel(ctxt, s, r)
-				}
-			}
-
-			o = Symaddr(r.Sym) + r.Add
-
-			// On amd64, 4-byte offsets will be sign-extended, so it is impossible to
-			// access more than 2GB of static data; fail at link time is better than
-			// fail at runtime. See https://golang.org/issue/7980.
-			// Instead of special casing only amd64, we treat this as an error on all
-			// 64-bit architectures so as to be future-proof.
-			if int32(o) < 0 && ctxt.Arch.PtrSize > 4 && siz == 4 {
-				Errorf(s, "non-pc-relative relocation address for %s is too big: %#x (%#x + %#x)", r.Sym.Name, uint64(o), Symaddr(r.Sym), r.Add)
-				errorexit()
-			}
-		case objabi.R_DWARFSECREF:
-			if r.Sym.Sect == nil {
-				Errorf(s, "missing DWARF section for relocation target %s", r.Sym.Name)
-			}
-
-			if ctxt.LinkMode == LinkExternal {
-				r.Done = false
-
-				// On most platforms, the external linker needs to adjust DWARF references
-				// as it combines DWARF sections. However, on Darwin, dsymutil does the
-				// DWARF linking, and it understands how to follow section offsets.
-				// Leaving in the relocation records confuses it (see
-				// https://golang.org/issue/22068) so drop them for Darwin.
-				if ctxt.HeadType == objabi.Hdarwin {
-					r.Done = true
-				}
-
-				// PE code emits IMAGE_REL_I386_SECREL and IMAGE_REL_AMD64_SECREL
-				// for R_DWARFSECREF relocations, while R_ADDR is replaced with
-				// IMAGE_REL_I386_DIR32, IMAGE_REL_AMD64_ADDR64 and IMAGE_REL_AMD64_ADDR32.
-				// Do not replace R_DWARFSECREF with R_ADDR for windows -
-				// let PE code emit correct relocations.
-				if ctxt.HeadType != objabi.Hwindows {
-					r.Type = objabi.R_ADDR
-				}
-
-				r.Xsym = ctxt.Syms.ROLookup(r.Sym.Sect.Name, 0)
-				r.Xadd = r.Add + Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr)
-
-				o = r.Xadd
-				if ctxt.IsELF && ctxt.Arch.Family == sys.AMD64 {
-					o = 0
-				}
-				break
-			}
-			o = Symaddr(r.Sym) + r.Add - int64(r.Sym.Sect.Vaddr)
-		case objabi.R_WEAKADDROFF:
-			if !r.Sym.Attr.Reachable() {
-				continue
-			}
-			fallthrough
-		case objabi.R_ADDROFF:
-			// The method offset tables using this relocation expect the offset to be relative
-			// to the start of the first text section, even if there are multiple.
-			if r.Sym.Sect.Name == ".text" {
-				o = Symaddr(r.Sym) - int64(Segtext.Sections[0].Vaddr) + r.Add
-			} else {
-				o = Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr) + r.Add
-			}
-
-		case objabi.R_ADDRCUOFF:
-			// debug_range and debug_loc elements use this relocation type to get an
-			// offset from the start of the compile unit.
-			o = Symaddr(r.Sym) + r.Add - Symaddr(r.Sym.Unit.Textp[0])
-
-			// r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call.
-		case objabi.R_GOTPCREL:
-			if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin && r.Sym != nil && r.Sym.Type != sym.SCONST {
-				r.Done = false
-				r.Xadd = r.Add
-				r.Xadd -= int64(r.Siz) // relative to address after the relocated chunk
-				r.Xsym = r.Sym
-
-				o = r.Xadd
-				o += int64(r.Siz)
-				break
-			}
-			fallthrough
-		case objabi.R_CALL, objabi.R_PCREL:
-			if ctxt.LinkMode == LinkExternal && r.Sym != nil && r.Sym.Type == sym.SUNDEFEXT {
-				// pass through to the external linker.
-				r.Done = false
-				r.Xadd = 0
-				if ctxt.IsELF {
-					r.Xadd -= int64(r.Siz)
-				}
-				r.Xsym = r.Sym
-				o = 0
-				break
-			}
-			if ctxt.LinkMode == LinkExternal && r.Sym != nil && r.Sym.Type != sym.SCONST && (r.Sym.Sect != s.Sect || r.Type == objabi.R_GOTPCREL) {
-				r.Done = false
-
-				// set up addend for eventual relocation via outer symbol.
-				rs := r.Sym
-
-				r.Xadd = r.Add
-				for rs.Outer != nil {
-					r.Xadd += Symaddr(rs) - Symaddr(rs.Outer)
-					rs = rs.Outer
-				}
-
-				r.Xadd -= int64(r.Siz) // relative to address after the relocated chunk
-				if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
-					Errorf(s, "missing section for relocation target %s", rs.Name)
-				}
-				r.Xsym = rs
-
-				o = r.Xadd
-				if ctxt.IsELF {
-					if ctxt.Arch.Family == sys.AMD64 {
-						o = 0
-					}
-				} else if ctxt.HeadType == objabi.Hdarwin {
-					if r.Type == objabi.R_CALL {
-						if ctxt.LinkMode == LinkExternal && rs.Type == sym.SDYNIMPORT {
-							if ctxt.Arch.Family == sys.AMD64 {
-								// AMD64 dynamic relocations are relative to the end of the relocation.
-								o += int64(r.Siz)
-							}
-						} else {
-							if rs.Type != sym.SHOSTOBJ {
-								o += int64(uint64(Symaddr(rs)) - rs.Sect.Vaddr)
-							}
-							o -= int64(r.Off) // relative to section offset, not symbol
-						}
-					} else {
-						o += int64(r.Siz)
-					}
-				} else if ctxt.HeadType == objabi.Hwindows && ctxt.Arch.Family == sys.AMD64 { // only amd64 needs PCREL
-					// PE/COFF's PC32 relocation uses the address after the relocated
-					// bytes as the base. Compensate by skewing the addend.
-					o += int64(r.Siz)
-				} else {
-					Errorf(s, "unhandled pcrel relocation to %s on %v", rs.Name, ctxt.HeadType)
-				}
-
-				break
-			}
-
-			o = 0
-			if r.Sym != nil {
-				o += Symaddr(r.Sym)
-			}
-
-			o += r.Add - (s.Value + int64(r.Off) + int64(r.Siz))
-		case objabi.R_SIZE:
-			o = r.Sym.Size + r.Add
-
-		case objabi.R_XCOFFREF:
-			if ctxt.HeadType != objabi.Haix {
-				Errorf(s, "find XCOFF R_REF on non-XCOFF files")
-			}
-			if ctxt.LinkMode != LinkExternal {
-				Errorf(s, "find XCOFF R_REF with internal linking")
-			}
-			r.Xsym = r.Sym
-			r.Xadd = r.Add
-			r.Done = false
-
-			// This isn't a real relocation so it must not update
-			// its offset value.
-			continue
-
-		case objabi.R_DWARFFILEREF:
-			// The final file index is saved in r.Add in dwarf.go:writelines.
-			o = r.Add
-		}
-
-		if ctxt.Arch.Family == sys.PPC64 || ctxt.Arch.Family == sys.S390X {
-			r.InitExt()
-			if r.Variant != sym.RV_NONE {
-				o = thearch.Archrelocvariant(ctxt, r, s, o)
-			}
-		}
-
-		if false {
-			nam := "<nil>"
-			var addr int64
-			if r.Sym != nil {
-				nam = r.Sym.Name
-				addr = Symaddr(r.Sym)
-			}
-			xnam := "<nil>"
-			if r.Xsym != nil {
-				xnam = r.Xsym.Name
-			}
-			fmt.Printf("relocate %s %#x (%#x+%#x, size %d) => %s %#x +%#x (xsym: %s +%#x) [type %d (%s)/%d, %x]\n", s.Name, s.Value+int64(off), s.Value, r.Off, r.Siz, nam, addr, r.Add, xnam, r.Xadd, r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Variant, o)
-		}
-		switch siz {
-		default:
-			Errorf(s, "bad reloc size %#x for %s", uint32(siz), r.Sym.Name)
-			fallthrough
-
-			// TODO(rsc): Remove.
-		case 1:
-			s.P[off] = byte(int8(o))
-		case 2:
-			if o != int64(int16(o)) {
-				Errorf(s, "relocation address for %s is too big: %#x", r.Sym.Name, o)
-			}
-			i16 := int16(o)
-			ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(i16))
-		case 4:
-			if r.Type == objabi.R_PCREL || r.Type == objabi.R_CALL {
-				if o != int64(int32(o)) {
-					Errorf(s, "pc-relative relocation address for %s is too big: %#x", r.Sym.Name, o)
-				}
-			} else {
-				if o != int64(int32(o)) && o != int64(uint32(o)) {
-					Errorf(s, "non-pc-relative relocation address for %s is too big: %#x", r.Sym.Name, uint64(o))
-				}
-			}
-
-			fl := int32(o)
-			ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(fl))
-		case 8:
-			ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(o))
-		}
-	}
-}
-
-func (ctxt *Link) reloc() {
-	for _, s := range ctxt.Textp {
-		relocsym(ctxt, s)
-	}
-	for _, s := range datap {
-		relocsym(ctxt, s)
-	}
-	for _, s := range dwarfp {
-		relocsym(ctxt, s)
-	}
-}
-
-func windynrelocsym(ctxt *Link, rel, s *sym.Symbol) {
-	for ri := range s.R {
-		r := &s.R[ri]
-		targ := r.Sym
-		if targ == nil {
-			continue
-		}
-		if !targ.Attr.Reachable() {
-			if r.Type == objabi.R_WEAKADDROFF {
-				continue
-			}
-			Errorf(s, "dynamic relocation to unreachable symbol %s", targ.Name)
-		}
-		if r.Sym.Plt() == -2 && r.Sym.Got() != -2 { // make dynimport JMP table for PE object files.
-			targ.SetPlt(int32(rel.Size))
-			r.Sym = rel
-			r.Add = int64(targ.Plt())
-
-			// jmp *addr
-			switch ctxt.Arch.Family {
-			default:
-				Errorf(s, "unsupported arch %v", ctxt.Arch.Family)
-				return
-			case sys.I386:
-				rel.AddUint8(0xff)
-				rel.AddUint8(0x25)
-				rel.AddAddr(ctxt.Arch, targ)
-				rel.AddUint8(0x90)
-				rel.AddUint8(0x90)
-			case sys.AMD64:
-				rel.AddUint8(0xff)
-				rel.AddUint8(0x24)
-				rel.AddUint8(0x25)
-				rel.AddAddrPlus4(targ, 0)
-				rel.AddUint8(0x90)
-			}
-		} else if r.Sym.Plt() >= 0 {
-			r.Sym = rel
-			r.Add = int64(targ.Plt())
-		}
-	}
-}
-
-// windynrelocsyms generates jump table to C library functions that will be
-// added later. windynrelocsyms writes the table into .rel symbol.
-func (ctxt *Link) windynrelocsyms() {
-	if !(ctxt.HeadType == objabi.Hwindows && iscgo && ctxt.LinkMode == LinkInternal) {
-		return
-	}
-
-	/* relocation table */
-	rel := ctxt.Syms.Lookup(".rel", 0)
-	rel.Attr |= sym.AttrReachable
-	rel.Type = sym.STEXT
-	ctxt.Textp = append(ctxt.Textp, rel)
-
-	for _, s := range ctxt.Textp {
-		if s == rel {
-			continue
-		}
-		windynrelocsym(ctxt, rel, s)
-	}
-}
-
-func dynrelocsym(ctxt *Link, s *sym.Symbol) {
-	for ri := range s.R {
-		r := &s.R[ri]
-		if ctxt.BuildMode == BuildModePIE && ctxt.LinkMode == LinkInternal {
-			// It's expected that some relocations will be done
-			// later by relocsym (R_TLS_LE, R_ADDROFF), so
-			// don't worry if Adddynrel returns false.
-			thearch.Adddynrel(ctxt, s, r)
-			continue
-		}
-
-		if r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT || r.Type >= objabi.ElfRelocOffset {
-			if r.Sym != nil && !r.Sym.Attr.Reachable() {
-				Errorf(s, "dynamic relocation to unreachable symbol %s", r.Sym.Name)
-			}
-			if !thearch.Adddynrel(ctxt, s, r) {
-				Errorf(s, "unsupported dynamic relocation for symbol %s (type=%d (%s) stype=%d (%s))", r.Sym.Name, r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Sym.Type, r.Sym.Type)
-			}
-		}
-	}
-}
-
-func dynreloc(ctxt *Link, data *[sym.SXREF][]*sym.Symbol) {
-	if ctxt.HeadType == objabi.Hwindows {
-		return
-	}
-	// -d suppresses dynamic loader format, so we may as well not
-	// compute these sections or mark their symbols as reachable.
-	if *FlagD {
-		return
-	}
-
-	for _, s := range ctxt.Textp {
-		dynrelocsym(ctxt, s)
-	}
-	for _, syms := range data {
-		for _, s := range syms {
-			dynrelocsym(ctxt, s)
-		}
-	}
-	if ctxt.IsELF {
-		elfdynhash(ctxt)
-	}
-}
-
-func Codeblk(ctxt *Link, addr int64, size int64) {
-	CodeblkPad(ctxt, addr, size, zeros[:])
-}
-func CodeblkPad(ctxt *Link, addr int64, size int64, pad []byte) {
-	if *flagA {
-		ctxt.Logf("codeblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset())
-	}
-
-	blk(ctxt.Out, ctxt.Textp, addr, size, pad)
-
-	/* again for printing */
-	if !*flagA {
-		return
-	}
-
-	syms := ctxt.Textp
-	for i, s := range syms {
-		if !s.Attr.Reachable() {
-			continue
-		}
-		if s.Value >= addr {
-			syms = syms[i:]
-			break
-		}
-	}
-
-	eaddr := addr + size
-	for _, s := range syms {
-		if !s.Attr.Reachable() {
-			continue
-		}
-		if s.Value >= eaddr {
-			break
-		}
-
-		if addr < s.Value {
-			ctxt.Logf("%-20s %.8x|", "_", uint64(addr))
-			for ; addr < s.Value; addr++ {
-				ctxt.Logf(" %.2x", 0)
-			}
-			ctxt.Logf("\n")
-		}
-
-		ctxt.Logf("%.6x\t%-20s\n", uint64(addr), s.Name)
-		q := s.P
-
-		for len(q) >= 16 {
-			ctxt.Logf("%.6x\t% x\n", uint64(addr), q[:16])
-			addr += 16
-			q = q[16:]
-		}
-
-		if len(q) > 0 {
-			ctxt.Logf("%.6x\t% x\n", uint64(addr), q)
-			addr += int64(len(q))
-		}
-	}
-
-	if addr < eaddr {
-		ctxt.Logf("%-20s %.8x|", "_", uint64(addr))
-		for ; addr < eaddr; addr++ {
-			ctxt.Logf(" %.2x", 0)
-		}
-	}
-}
-
-func blk(out *OutBuf, syms []*sym.Symbol, addr, size int64, pad []byte) {
-	for i, s := range syms {
-		if !s.Attr.SubSymbol() && s.Value >= addr {
-			syms = syms[i:]
-			break
-		}
-	}
-
-	// This doesn't distinguish the memory size from the file
-	// size, and it lays out the file based on Symbol.Value, which
-	// is the virtual address. DWARF compression changes file sizes,
-	// so dwarfcompress will fix this up later if necessary.
-	eaddr := addr + size
-	for _, s := range syms {
-		if s.Attr.SubSymbol() {
-			continue
-		}
-		if s.Value >= eaddr {
-			break
-		}
-		if s.Value < addr {
-			Errorf(s, "phase error: addr=%#x but sym=%#x type=%d", addr, s.Value, s.Type)
-			errorexit()
-		}
-		if addr < s.Value {
-			out.WriteStringPad("", int(s.Value-addr), pad)
-			addr = s.Value
-		}
-		out.WriteSym(s)
-		addr += int64(len(s.P))
-		if addr < s.Value+s.Size {
-			out.WriteStringPad("", int(s.Value+s.Size-addr), pad)
-			addr = s.Value + s.Size
-		}
-		if addr != s.Value+s.Size {
-			Errorf(s, "phase error: addr=%#x value+size=%#x", addr, s.Value+s.Size)
-			errorexit()
-		}
-		if s.Value+s.Size >= eaddr {
-			break
-		}
-	}
-
-	if addr < eaddr {
-		out.WriteStringPad("", int(eaddr-addr), pad)
-	}
-	out.Flush()
-}
-
-func Datblk(ctxt *Link, addr int64, size int64) {
-	writeDatblkToOutBuf(ctxt, ctxt.Out, addr, size)
-}
-
-// Used only on Wasm for now.
-func DatblkBytes(ctxt *Link, addr int64, size int64) []byte {
-	buf := bytes.NewBuffer(make([]byte, 0, size))
-	out := &OutBuf{w: bufio.NewWriter(buf)}
-	writeDatblkToOutBuf(ctxt, out, addr, size)
-	out.Flush()
-	return buf.Bytes()
-}
-
-func writeDatblkToOutBuf(ctxt *Link, out *OutBuf, addr int64, size int64) {
-	if *flagA {
-		ctxt.Logf("datblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset())
-	}
-
-	blk(out, datap, addr, size, zeros[:])
-
-	/* again for printing */
-	if !*flagA {
-		return
-	}
-
-	syms := datap
-	for i, sym := range syms {
-		if sym.Value >= addr {
-			syms = syms[i:]
-			break
-		}
-	}
-
-	eaddr := addr + size
-	for _, sym := range syms {
-		if sym.Value >= eaddr {
-			break
-		}
-		if addr < sym.Value {
-			ctxt.Logf("\t%.8x| 00 ...\n", uint64(addr))
-			addr = sym.Value
-		}
-
-		ctxt.Logf("%s\n\t%.8x|", sym.Name, uint64(addr))
-		for i, b := range sym.P {
-			if i > 0 && i%16 == 0 {
-				ctxt.Logf("\n\t%.8x|", uint64(addr)+uint64(i))
-			}
-			ctxt.Logf(" %.2x", b)
-		}
-
-		addr += int64(len(sym.P))
-		for ; addr < sym.Value+sym.Size; addr++ {
-			ctxt.Logf(" %.2x", 0)
-		}
-		ctxt.Logf("\n")
-
-		if ctxt.LinkMode != LinkExternal {
-			continue
-		}
-		for i := range sym.R {
-			r := &sym.R[i] // Copying sym.Reloc has measurable impact on performance
-			rsname := ""
-			rsval := int64(0)
-			if r.Sym != nil {
-				rsname = r.Sym.Name
-				rsval = r.Sym.Value
-			}
-			typ := "?"
-			switch r.Type {
-			case objabi.R_ADDR:
-				typ = "addr"
-			case objabi.R_PCREL:
-				typ = "pcrel"
-			case objabi.R_CALL:
-				typ = "call"
-			}
-			ctxt.Logf("\treloc %.8x/%d %s %s+%#x [%#x]\n", uint(sym.Value+int64(r.Off)), r.Siz, typ, rsname, r.Add, rsval+r.Add)
-		}
-	}
-
-	if addr < eaddr {
-		ctxt.Logf("\t%.8x| 00 ...\n", uint(addr))
-	}
-	ctxt.Logf("\t%.8x|\n", uint(eaddr))
-}
-
-func Dwarfblk(ctxt *Link, addr int64, size int64) {
-	if *flagA {
-		ctxt.Logf("dwarfblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset())
-	}
-
-	blk(ctxt.Out, dwarfp, addr, size, zeros[:])
-}
-
-var zeros [512]byte
-
-var (
-	strdata  = make(map[string]string)
-	strnames []string
-)
-
-func addstrdata1(ctxt *Link, arg string) {
-	eq := strings.Index(arg, "=")
-	dot := strings.LastIndex(arg[:eq+1], ".")
-	if eq < 0 || dot < 0 {
-		Exitf("-X flag requires argument of the form importpath.name=value")
-	}
-	pkg := arg[:dot]
-	if ctxt.BuildMode == BuildModePlugin && pkg == "main" {
-		pkg = *flagPluginPath
-	}
-	pkg = objabi.PathToPrefix(pkg)
-	name := pkg + arg[dot:eq]
-	value := arg[eq+1:]
-	if _, ok := strdata[name]; !ok {
-		strnames = append(strnames, name)
-	}
-	strdata[name] = value
-}
-
-// addstrdata sets the initial value of the string variable name to value.
-func addstrdata(ctxt *Link, name, value string) {
-	s := ctxt.Syms.ROLookup(name, 0)
-	if s == nil || s.Gotype == nil {
-		// Not defined in the loaded packages.
-		return
-	}
-	if s.Gotype.Name != "type.string" {
-		Errorf(s, "cannot set with -X: not a var of type string (%s)", s.Gotype.Name)
-		return
-	}
-	if s.Type == sym.SBSS {
-		s.Type = sym.SDATA
-	}
-
-	p := fmt.Sprintf("%s.str", s.Name)
-	sp := ctxt.Syms.Lookup(p, 0)
-
-	Addstring(sp, value)
-	sp.Type = sym.SRODATA
-
-	s.Size = 0
-	s.P = s.P[:0]
-	if s.Attr.ReadOnly() {
-		s.P = make([]byte, 0, ctxt.Arch.PtrSize*2)
-		s.Attr.Set(sym.AttrReadOnly, false)
-	}
-	s.R = s.R[:0]
-	reachable := s.Attr.Reachable()
-	s.AddAddr(ctxt.Arch, sp)
-	s.AddUint(ctxt.Arch, uint64(len(value)))
-
-	// addstring, addaddr, etc., mark the symbols as reachable.
-	// In this case that is not necessarily true, so stick to what
-	// we know before entering this function.
-	s.Attr.Set(sym.AttrReachable, reachable)
-
-	sp.Attr.Set(sym.AttrReachable, reachable)
-}
-
-func (ctxt *Link) dostrdata() {
-	for _, name := range strnames {
-		addstrdata(ctxt, name, strdata[name])
-	}
-}
-
-func Addstring(s *sym.Symbol, str string) int64 {
-	if s.Type == 0 {
-		s.Type = sym.SNOPTRDATA
-	}
-	s.Attr |= sym.AttrReachable
-	r := s.Size
-	if s.Name == ".shstrtab" {
-		elfsetstring(s, str, int(r))
-	}
-	s.P = append(s.P, str...)
-	s.P = append(s.P, 0)
-	s.Size = int64(len(s.P))
-	return r
-}
-
-// addgostring adds str, as a Go string value, to s. symname is the name of the
-// symbol used to define the string data and must be unique per linked object.
-func addgostring(ctxt *Link, s *sym.Symbol, symname, str string) {
-	sdata := ctxt.Syms.Lookup(symname, 0)
-	if sdata.Type != sym.Sxxx {
-		Errorf(s, "duplicate symname in addgostring: %s", symname)
-	}
-	sdata.Attr |= sym.AttrReachable
-	sdata.Attr |= sym.AttrLocal
-	sdata.Type = sym.SRODATA
-	sdata.Size = int64(len(str))
-	sdata.P = []byte(str)
-	s.AddAddr(ctxt.Arch, sdata)
-	s.AddUint(ctxt.Arch, uint64(len(str)))
-}
-
-func addinitarrdata(ctxt *Link, s *sym.Symbol) {
-	p := s.Name + ".ptr"
-	sp := ctxt.Syms.Lookup(p, 0)
-	sp.Type = sym.SINITARR
-	sp.Size = 0
-	sp.Attr |= sym.AttrDuplicateOK
-	sp.AddAddr(ctxt.Arch, s)
-}
-
-// symalign returns the required alignment for the given symbol s.
-func symalign(s *sym.Symbol) int32 {
-	min := int32(thearch.Minalign)
-	if s.Align >= min {
-		return s.Align
-	} else if s.Align != 0 {
-		return min
-	}
-	if strings.HasPrefix(s.Name, "go.string.") || strings.HasPrefix(s.Name, "type..namedata.") {
-		// String data is just bytes.
-		// If we align it, we waste a lot of space to padding.
-		return min
-	}
-	align := int32(thearch.Maxalign)
-	for int64(align) > s.Size && align > min {
-		align >>= 1
-	}
-	s.Align = align
-	return align
-}
-
-func aligndatsize(datsize int64, s *sym.Symbol) int64 {
-	return Rnd(datsize, int64(symalign(s)))
-}
-
-const debugGCProg = false
-
-type GCProg struct {
-	ctxt *Link
-	sym  *sym.Symbol
-	w    gcprog.Writer
-}
-
-func (p *GCProg) Init(ctxt *Link, name string) {
-	p.ctxt = ctxt
-	p.sym = ctxt.Syms.Lookup(name, 0)
-	p.w.Init(p.writeByte(ctxt))
-	if debugGCProg {
-		fmt.Fprintf(os.Stderr, "ld: start GCProg %s\n", name)
-		p.w.Debug(os.Stderr)
-	}
-}
-
-func (p *GCProg) writeByte(ctxt *Link) func(x byte) {
-	return func(x byte) {
-		p.sym.AddUint8(x)
-	}
-}
-
-func (p *GCProg) End(size int64) {
-	p.w.ZeroUntil(size / int64(p.ctxt.Arch.PtrSize))
-	p.w.End()
-	if debugGCProg {
-		fmt.Fprintf(os.Stderr, "ld: end GCProg\n")
-	}
-}
-
-func (p *GCProg) AddSym(s *sym.Symbol) {
-	typ := s.Gotype
-	// Things without pointers should be in sym.SNOPTRDATA or sym.SNOPTRBSS;
-	// everything we see should have pointers and should therefore have a type.
-	if typ == nil {
-		switch s.Name {
-		case "runtime.data", "runtime.edata", "runtime.bss", "runtime.ebss":
-			// Ignore special symbols that are sometimes laid out
-			// as real symbols. See comment about dyld on darwin in
-			// the address function.
-			return
-		}
-		Errorf(s, "missing Go type information for global symbol: size %d", s.Size)
-		return
-	}
-
-	ptrsize := int64(p.ctxt.Arch.PtrSize)
-	nptr := decodetypePtrdata(p.ctxt.Arch, typ.P) / ptrsize
-
-	if debugGCProg {
-		fmt.Fprintf(os.Stderr, "gcprog sym: %s at %d (ptr=%d+%d)\n", s.Name, s.Value, s.Value/ptrsize, nptr)
-	}
-
-	if decodetypeUsegcprog(p.ctxt.Arch, typ.P) == 0 {
-		// Copy pointers from mask into program.
-		mask := decodetypeGcmask(p.ctxt, typ)
-		for i := int64(0); i < nptr; i++ {
-			if (mask[i/8]>>uint(i%8))&1 != 0 {
-				p.w.Ptr(s.Value/ptrsize + i)
-			}
-		}
-		return
-	}
-
-	// Copy program.
-	prog := decodetypeGcprog(p.ctxt, typ)
-	p.w.ZeroUntil(s.Value / ptrsize)
-	p.w.Append(prog[4:], nptr)
-}
-
-// dataSortKey is used to sort a slice of data symbol *sym.Symbol pointers.
-// The sort keys are kept inline to improve cache behavior while sorting.
-type dataSortKey struct {
-	size int64
-	name string
-	sym  *sym.Symbol
-}
-
-type bySizeAndName []dataSortKey
-
-func (d bySizeAndName) Len() int      { return len(d) }
-func (d bySizeAndName) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
-func (d bySizeAndName) Less(i, j int) bool {
-	s1, s2 := d[i], d[j]
-	if s1.size != s2.size {
-		return s1.size < s2.size
-	}
-	return s1.name < s2.name
-}
-
-// cutoff is the maximum data section size permitted by the linker
-// (see issue #9862).
-const cutoff = 2e9 // 2 GB (or so; looks better in errors than 2^31)
-
-func checkdatsize(ctxt *Link, datsize int64, symn sym.SymKind) {
-	if datsize > cutoff {
-		Errorf(nil, "too much data in section %v (over %v bytes)", symn, cutoff)
-	}
-}
-
-// datap is a collection of reachable data symbols in address order.
-// Generated by dodata.
-var datap []*sym.Symbol
-
-func (ctxt *Link) dodata() {
-	if (ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
-		// The values in moduledata are filled out by relocations
-		// pointing to the addresses of these special symbols.
-		// Typically these symbols have no size and are not laid
-		// out with their matching section.
-		//
-		// However on darwin, dyld will find the special symbol
-		// in the first loaded module, even though it is local.
-		//
-		// (An hypothesis, formed without looking in the dyld sources:
-		// these special symbols have no size, so their address
-		// matches a real symbol. The dynamic linker assumes we
-		// want the normal symbol with the same address and finds
-		// it in the other module.)
-		//
-		// To work around this we lay out the symbls whose
-		// addresses are vital for multi-module programs to work
-		// as normal symbols, and give them a little size.
-		//
-		// On AIX, as all DATA sections are merged together, ld might not put
-		// these symbols at the beginning of their respective section if there
-		// aren't real symbols, their alignment might not match the
-		// first symbol alignment. Therefore, there are explicitly put at the
-		// beginning of their section with the same alignment.
-		bss := ctxt.Syms.Lookup("runtime.bss", 0)
-		bss.Size = 8
-		bss.Attr.Set(sym.AttrSpecial, false)
-
-		ctxt.Syms.Lookup("runtime.ebss", 0).Attr.Set(sym.AttrSpecial, false)
-
-		data := ctxt.Syms.Lookup("runtime.data", 0)
-		data.Size = 8
-		data.Attr.Set(sym.AttrSpecial, false)
-
-		edata := ctxt.Syms.Lookup("runtime.edata", 0)
-		edata.Attr.Set(sym.AttrSpecial, false)
-		if ctxt.HeadType == objabi.Haix {
-			// XCOFFTOC symbols are part of .data section.
-			edata.Type = sym.SXCOFFTOC
-		}
-
-		types := ctxt.Syms.Lookup("runtime.types", 0)
-		types.Type = sym.STYPE
-		types.Size = 8
-		types.Attr.Set(sym.AttrSpecial, false)
-
-		etypes := ctxt.Syms.Lookup("runtime.etypes", 0)
-		etypes.Type = sym.SFUNCTAB
-		etypes.Attr.Set(sym.AttrSpecial, false)
-
-		if ctxt.HeadType == objabi.Haix {
-			rodata := ctxt.Syms.Lookup("runtime.rodata", 0)
-			rodata.Type = sym.SSTRING
-			rodata.Size = 8
-			rodata.Attr.Set(sym.AttrSpecial, false)
-
-			ctxt.Syms.Lookup("runtime.erodata", 0).Attr.Set(sym.AttrSpecial, false)
-
-		}
-	}
-
-	// Collect data symbols by type into data.
-	var data [sym.SXREF][]*sym.Symbol
-	for _, s := range ctxt.Syms.Allsym {
-		if !s.Attr.Reachable() || s.Attr.Special() || s.Attr.SubSymbol() {
-			continue
-		}
-		if s.Type <= sym.STEXT || s.Type >= sym.SXREF {
-			continue
-		}
-		data[s.Type] = append(data[s.Type], s)
-	}
-
-	// Now that we have the data symbols, but before we start
-	// to assign addresses, record all the necessary
-	// dynamic relocations. These will grow the relocation
-	// symbol, which is itself data.
-	//
-	// On darwin, we need the symbol table numbers for dynreloc.
-	if ctxt.HeadType == objabi.Hdarwin {
-		machosymorder(ctxt)
-	}
-	dynreloc(ctxt, &data)
-
-	if ctxt.UseRelro() {
-		// "read only" data with relocations needs to go in its own section
-		// when building a shared library. We do this by boosting objects of
-		// type SXXX with relocations to type SXXXRELRO.
-		for _, symnro := range sym.ReadOnly {
-			symnrelro := sym.RelROMap[symnro]
-
-			ro := []*sym.Symbol{}
-			relro := data[symnrelro]
-
-			for _, s := range data[symnro] {
-				isRelro := len(s.R) > 0
-				switch s.Type {
-				case sym.STYPE, sym.STYPERELRO, sym.SGOFUNCRELRO:
-					// Symbols are not sorted yet, so it is possible
-					// that an Outer symbol has been changed to a
-					// relro Type before it reaches here.
-					isRelro = true
-				case sym.SFUNCTAB:
-					if ctxt.HeadType == objabi.Haix && s.Name == "runtime.etypes" {
-						// runtime.etypes must be at the end of
-						// the relro datas.
-						isRelro = true
-					}
-				}
-				if isRelro {
-					s.Type = symnrelro
-					if s.Outer != nil {
-						s.Outer.Type = s.Type
-					}
-					relro = append(relro, s)
-				} else {
-					ro = append(ro, s)
-				}
-			}
-
-			// Check that we haven't made two symbols with the same .Outer into
-			// different types (because references two symbols with non-nil Outer
-			// become references to the outer symbol + offset it's vital that the
-			// symbol and the outer end up in the same section).
-			for _, s := range relro {
-				if s.Outer != nil && s.Outer.Type != s.Type {
-					Errorf(s, "inconsistent types for symbol and its Outer %s (%v != %v)",
-						s.Outer.Name, s.Type, s.Outer.Type)
-				}
-			}
-
-			data[symnro] = ro
-			data[symnrelro] = relro
-		}
-	}
-
-	// Sort symbols.
-	var dataMaxAlign [sym.SXREF]int32
-	var wg sync.WaitGroup
-	for symn := range data {
-		symn := sym.SymKind(symn)
-		wg.Add(1)
-		go func() {
-			data[symn], dataMaxAlign[symn] = dodataSect(ctxt, symn, data[symn])
-			wg.Done()
-		}()
-	}
-	wg.Wait()
-
-	if ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal {
-		// These symbols must have the same alignment as their section.
-		// Otherwize, ld might change the layout of Go sections.
-		ctxt.Syms.ROLookup("runtime.data", 0).Align = dataMaxAlign[sym.SDATA]
-		ctxt.Syms.ROLookup("runtime.bss", 0).Align = dataMaxAlign[sym.SBSS]
-	}
-
-	// Allocate sections.
-	// Data is processed before segtext, because we need
-	// to see all symbols in the .data and .bss sections in order
-	// to generate garbage collection information.
-	datsize := int64(0)
-
-	// Writable data sections that do not need any specialized handling.
-	writable := []sym.SymKind{
-		sym.SBUILDINFO,
-		sym.SELFSECT,
-		sym.SMACHO,
-		sym.SMACHOGOT,
-		sym.SWINDOWS,
-	}
-	for _, symn := range writable {
-		for _, s := range data[symn] {
-			sect := addsection(ctxt.Arch, &Segdata, s.Name, 06)
-			sect.Align = symalign(s)
-			datsize = Rnd(datsize, int64(sect.Align))
-			sect.Vaddr = uint64(datsize)
-			s.Sect = sect
-			s.Type = sym.SDATA
-			s.Value = int64(uint64(datsize) - sect.Vaddr)
-			datsize += s.Size
-			sect.Length = uint64(datsize) - sect.Vaddr
-		}
-		checkdatsize(ctxt, datsize, symn)
-	}
-
-	// .got (and .toc on ppc64)
-	if len(data[sym.SELFGOT]) > 0 {
-		sect := addsection(ctxt.Arch, &Segdata, ".got", 06)
-		sect.Align = dataMaxAlign[sym.SELFGOT]
-		datsize = Rnd(datsize, int64(sect.Align))
-		sect.Vaddr = uint64(datsize)
-		for _, s := range data[sym.SELFGOT] {
-			datsize = aligndatsize(datsize, s)
-			s.Sect = sect
-			s.Type = sym.SDATA
-			s.Value = int64(uint64(datsize) - sect.Vaddr)
-
-			// Resolve .TOC. symbol for this object file (ppc64)
-			toc := ctxt.Syms.ROLookup(".TOC.", int(s.Version))
-			if toc != nil {
-				toc.Sect = sect
-				toc.Outer = s
-				toc.Sub = s.Sub
-				s.Sub = toc
-
-				toc.Value = 0x8000
-			}
-
-			datsize += s.Size
-		}
-		checkdatsize(ctxt, datsize, sym.SELFGOT)
-		sect.Length = uint64(datsize) - sect.Vaddr
-	}
-
-	/* pointer-free data */
-	sect := addsection(ctxt.Arch, &Segdata, ".noptrdata", 06)
-	sect.Align = dataMaxAlign[sym.SNOPTRDATA]
-	datsize = Rnd(datsize, int64(sect.Align))
-	sect.Vaddr = uint64(datsize)
-	ctxt.Syms.Lookup("runtime.noptrdata", 0).Sect = sect
-	ctxt.Syms.Lookup("runtime.enoptrdata", 0).Sect = sect
-	for _, s := range data[sym.SNOPTRDATA] {
-		datsize = aligndatsize(datsize, s)
-		s.Sect = sect
-		s.Type = sym.SDATA
-		s.Value = int64(uint64(datsize) - sect.Vaddr)
-		datsize += s.Size
-	}
-	checkdatsize(ctxt, datsize, sym.SNOPTRDATA)
-	sect.Length = uint64(datsize) - sect.Vaddr
-
-	hasinitarr := ctxt.linkShared
-
-	/* shared library initializer */
-	switch ctxt.BuildMode {
-	case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin:
-		hasinitarr = true
-	}
-
-	if ctxt.HeadType == objabi.Haix {
-		if len(data[sym.SINITARR]) > 0 {
-			Errorf(nil, "XCOFF format doesn't allow .init_array section")
-		}
-	}
-
-	if hasinitarr && len(data[sym.SINITARR]) > 0 {
-		sect := addsection(ctxt.Arch, &Segdata, ".init_array", 06)
-		sect.Align = dataMaxAlign[sym.SINITARR]
-		datsize = Rnd(datsize, int64(sect.Align))
-		sect.Vaddr = uint64(datsize)
-		for _, s := range data[sym.SINITARR] {
-			datsize = aligndatsize(datsize, s)
-			s.Sect = sect
-			s.Value = int64(uint64(datsize) - sect.Vaddr)
-			datsize += s.Size
-		}
-		sect.Length = uint64(datsize) - sect.Vaddr
-		checkdatsize(ctxt, datsize, sym.SINITARR)
-	}
-
-	/* data */
-	sect = addsection(ctxt.Arch, &Segdata, ".data", 06)
-	sect.Align = dataMaxAlign[sym.SDATA]
-	datsize = Rnd(datsize, int64(sect.Align))
-	sect.Vaddr = uint64(datsize)
-	ctxt.Syms.Lookup("runtime.data", 0).Sect = sect
-	ctxt.Syms.Lookup("runtime.edata", 0).Sect = sect
-	var gc GCProg
-	gc.Init(ctxt, "runtime.gcdata")
-	for _, s := range data[sym.SDATA] {
-		s.Sect = sect
-		s.Type = sym.SDATA
-		datsize = aligndatsize(datsize, s)
-		s.Value = int64(uint64(datsize) - sect.Vaddr)
-		gc.AddSym(s)
-		datsize += s.Size
-	}
-	gc.End(datsize - int64(sect.Vaddr))
-	// On AIX, TOC entries must be the last of .data
-	// These aren't part of gc as they won't change during the runtime.
-	for _, s := range data[sym.SXCOFFTOC] {
-		s.Sect = sect
-		s.Type = sym.SDATA
-		datsize = aligndatsize(datsize, s)
-		s.Value = int64(uint64(datsize) - sect.Vaddr)
-		datsize += s.Size
-	}
-	checkdatsize(ctxt, datsize, sym.SDATA)
-	sect.Length = uint64(datsize) - sect.Vaddr
-
-	/* bss */
-	sect = addsection(ctxt.Arch, &Segdata, ".bss", 06)
-	sect.Align = dataMaxAlign[sym.SBSS]
-	datsize = Rnd(datsize, int64(sect.Align))
-	sect.Vaddr = uint64(datsize)
-	ctxt.Syms.Lookup("runtime.bss", 0).Sect = sect
-	ctxt.Syms.Lookup("runtime.ebss", 0).Sect = sect
-	gc = GCProg{}
-	gc.Init(ctxt, "runtime.gcbss")
-	for _, s := range data[sym.SBSS] {
-		s.Sect = sect
-		datsize = aligndatsize(datsize, s)
-		s.Value = int64(uint64(datsize) - sect.Vaddr)
-		gc.AddSym(s)
-		datsize += s.Size
-	}
-	checkdatsize(ctxt, datsize, sym.SBSS)
-	sect.Length = uint64(datsize) - sect.Vaddr
-	gc.End(int64(sect.Length))
-
-	/* pointer-free bss */
-	sect = addsection(ctxt.Arch, &Segdata, ".noptrbss", 06)
-	sect.Align = dataMaxAlign[sym.SNOPTRBSS]
-	datsize = Rnd(datsize, int64(sect.Align))
-	sect.Vaddr = uint64(datsize)
-	ctxt.Syms.Lookup("runtime.noptrbss", 0).Sect = sect
-	ctxt.Syms.Lookup("runtime.enoptrbss", 0).Sect = sect
-	for _, s := range data[sym.SNOPTRBSS] {
-		datsize = aligndatsize(datsize, s)
-		s.Sect = sect
-		s.Value = int64(uint64(datsize) - sect.Vaddr)
-		datsize += s.Size
-	}
-	sect.Length = uint64(datsize) - sect.Vaddr
-	ctxt.Syms.Lookup("runtime.end", 0).Sect = sect
-	checkdatsize(ctxt, datsize, sym.SNOPTRBSS)
-
-	// Coverage instrumentation counters for libfuzzer.
-	if len(data[sym.SLIBFUZZER_EXTRA_COUNTER]) > 0 {
-		sect := addsection(ctxt.Arch, &Segdata, "__libfuzzer_extra_counters", 06)
-		sect.Align = dataMaxAlign[sym.SLIBFUZZER_EXTRA_COUNTER]
-		datsize = Rnd(datsize, int64(sect.Align))
-		sect.Vaddr = uint64(datsize)
-		for _, s := range data[sym.SLIBFUZZER_EXTRA_COUNTER] {
-			datsize = aligndatsize(datsize, s)
-			s.Sect = sect
-			s.Value = int64(uint64(datsize) - sect.Vaddr)
-			datsize += s.Size
-		}
-		sect.Length = uint64(datsize) - sect.Vaddr
-		checkdatsize(ctxt, datsize, sym.SLIBFUZZER_EXTRA_COUNTER)
-	}
-
-	if len(data[sym.STLSBSS]) > 0 {
-		var sect *sym.Section
-		if (ctxt.IsELF || ctxt.HeadType == objabi.Haix) && (ctxt.LinkMode == LinkExternal || !*FlagD) {
-			sect = addsection(ctxt.Arch, &Segdata, ".tbss", 06)
-			sect.Align = int32(ctxt.Arch.PtrSize)
-			sect.Vaddr = 0
-		}
-		datsize = 0
-
-		for _, s := range data[sym.STLSBSS] {
-			datsize = aligndatsize(datsize, s)
-			s.Sect = sect
-			s.Value = datsize
-			datsize += s.Size
-		}
-		checkdatsize(ctxt, datsize, sym.STLSBSS)
-
-		if sect != nil {
-			sect.Length = uint64(datsize)
-		}
-	}
-
-	/*
-	 * We finished data, begin read-only data.
-	 * Not all systems support a separate read-only non-executable data section.
-	 * ELF and Windows PE systems do.
-	 * OS X and Plan 9 do not.
-	 * And if we're using external linking mode, the point is moot,
-	 * since it's not our decision; that code expects the sections in
-	 * segtext.
-	 */
-	var segro *sym.Segment
-	if ctxt.IsELF && ctxt.LinkMode == LinkInternal {
-		segro = &Segrodata
-	} else if ctxt.HeadType == objabi.Hwindows {
-		segro = &Segrodata
-	} else {
-		segro = &Segtext
-	}
-
-	datsize = 0
-
-	/* read-only executable ELF, Mach-O sections */
-	if len(data[sym.STEXT]) != 0 {
-		Errorf(nil, "dodata found an sym.STEXT symbol: %s", data[sym.STEXT][0].Name)
-	}
-	for _, s := range data[sym.SELFRXSECT] {
-		sect := addsection(ctxt.Arch, &Segtext, s.Name, 04)
-		sect.Align = symalign(s)
-		datsize = Rnd(datsize, int64(sect.Align))
-		sect.Vaddr = uint64(datsize)
-		s.Sect = sect
-		s.Type = sym.SRODATA
-		s.Value = int64(uint64(datsize) - sect.Vaddr)
-		datsize += s.Size
-		sect.Length = uint64(datsize) - sect.Vaddr
-		checkdatsize(ctxt, datsize, sym.SELFRXSECT)
-	}
-
-	/* read-only data */
-	sect = addsection(ctxt.Arch, segro, ".rodata", 04)
-
-	sect.Vaddr = 0
-	ctxt.Syms.Lookup("runtime.rodata", 0).Sect = sect
-	ctxt.Syms.Lookup("runtime.erodata", 0).Sect = sect
-	if !ctxt.UseRelro() {
-		ctxt.Syms.Lookup("runtime.types", 0).Sect = sect
-		ctxt.Syms.Lookup("runtime.etypes", 0).Sect = sect
-	}
-	for _, symn := range sym.ReadOnly {
-		align := dataMaxAlign[symn]
-		if sect.Align < align {
-			sect.Align = align
-		}
-	}
-	datsize = Rnd(datsize, int64(sect.Align))
-	for _, symn := range sym.ReadOnly {
-		symnStartValue := datsize
-		for _, s := range data[symn] {
-			datsize = aligndatsize(datsize, s)
-			s.Sect = sect
-			s.Type = sym.SRODATA
-			s.Value = int64(uint64(datsize) - sect.Vaddr)
-			datsize += s.Size
-		}
-		checkdatsize(ctxt, datsize, symn)
-		if ctxt.HeadType == objabi.Haix {
-			// Read-only symbols might be wrapped inside their outer
-			// symbol.
-			// XCOFF symbol table needs to know the size of
-			// these outer symbols.
-			xcoffUpdateOuterSize(ctxt, datsize-symnStartValue, symn)
-		}
-	}
-	sect.Length = uint64(datsize) - sect.Vaddr
-
-	/* read-only ELF, Mach-O sections */
-	for _, s := range data[sym.SELFROSECT] {
-		sect = addsection(ctxt.Arch, segro, s.Name, 04)
-		sect.Align = symalign(s)
-		datsize = Rnd(datsize, int64(sect.Align))
-		sect.Vaddr = uint64(datsize)
-		s.Sect = sect
-		s.Type = sym.SRODATA
-		s.Value = int64(uint64(datsize) - sect.Vaddr)
-		datsize += s.Size
-		sect.Length = uint64(datsize) - sect.Vaddr
-	}
-	checkdatsize(ctxt, datsize, sym.SELFROSECT)
-
-	for _, s := range data[sym.SMACHOPLT] {
-		sect = addsection(ctxt.Arch, segro, s.Name, 04)
-		sect.Align = symalign(s)
-		datsize = Rnd(datsize, int64(sect.Align))
-		sect.Vaddr = uint64(datsize)
-		s.Sect = sect
-		s.Type = sym.SRODATA
-		s.Value = int64(uint64(datsize) - sect.Vaddr)
-		datsize += s.Size
-		sect.Length = uint64(datsize) - sect.Vaddr
-	}
-	checkdatsize(ctxt, datsize, sym.SMACHOPLT)
-
-	// There is some data that are conceptually read-only but are written to by
-	// relocations. On GNU systems, we can arrange for the dynamic linker to
-	// mprotect sections after relocations are applied by giving them write
-	// permissions in the object file and calling them ".data.rel.ro.FOO". We
-	// divide the .rodata section between actual .rodata and .data.rel.ro.rodata,
-	// but for the other sections that this applies to, we just write a read-only
-	// .FOO section or a read-write .data.rel.ro.FOO section depending on the
-	// situation.
-	// TODO(mwhudson): It would make sense to do this more widely, but it makes
-	// the system linker segfault on darwin.
-	addrelrosection := func(suffix string) *sym.Section {
-		return addsection(ctxt.Arch, segro, suffix, 04)
-	}
-
-	if ctxt.UseRelro() {
-		segrelro := &Segrelrodata
-		if ctxt.LinkMode == LinkExternal && ctxt.HeadType != objabi.Haix {
-			// Using a separate segment with an external
-			// linker results in some programs moving
-			// their data sections unexpectedly, which
-			// corrupts the moduledata. So we use the
-			// rodata segment and let the external linker
-			// sort out a rel.ro segment.
-			segrelro = segro
-		} else {
-			// Reset datsize for new segment.
-			datsize = 0
-		}
-
-		addrelrosection = func(suffix string) *sym.Section {
-			return addsection(ctxt.Arch, segrelro, ".data.rel.ro"+suffix, 06)
-		}
-
-		/* data only written by relocations */
-		sect = addrelrosection("")
-
-		ctxt.Syms.Lookup("runtime.types", 0).Sect = sect
-		ctxt.Syms.Lookup("runtime.etypes", 0).Sect = sect
-
-		for _, symnro := range sym.ReadOnly {
-			symn := sym.RelROMap[symnro]
-			align := dataMaxAlign[symn]
-			if sect.Align < align {
-				sect.Align = align
-			}
-		}
-		datsize = Rnd(datsize, int64(sect.Align))
-		sect.Vaddr = uint64(datsize)
-
-		for i, symnro := range sym.ReadOnly {
-			if i == 0 && symnro == sym.STYPE && ctxt.HeadType != objabi.Haix {
-				// Skip forward so that no type
-				// reference uses a zero offset.
-				// This is unlikely but possible in small
-				// programs with no other read-only data.
-				datsize++
-			}
-
-			symn := sym.RelROMap[symnro]
-			symnStartValue := datsize
-			for _, s := range data[symn] {
-				datsize = aligndatsize(datsize, s)
-				if s.Outer != nil && s.Outer.Sect != nil && s.Outer.Sect != sect {
-					Errorf(s, "s.Outer (%s) in different section from s, %s != %s", s.Outer.Name, s.Outer.Sect.Name, sect.Name)
-				}
-				s.Sect = sect
-				s.Type = sym.SRODATA
-				s.Value = int64(uint64(datsize) - sect.Vaddr)
-				datsize += s.Size
-			}
-			checkdatsize(ctxt, datsize, symn)
-			if ctxt.HeadType == objabi.Haix {
-				// Read-only symbols might be wrapped inside their outer
-				// symbol.
-				// XCOFF symbol table needs to know the size of
-				// these outer symbols.
-				xcoffUpdateOuterSize(ctxt, datsize-symnStartValue, symn)
-			}
-		}
-
-		sect.Length = uint64(datsize) - sect.Vaddr
-	}
-
-	/* typelink */
-	sect = addrelrosection(".typelink")
-	sect.Align = dataMaxAlign[sym.STYPELINK]
-	datsize = Rnd(datsize, int64(sect.Align))
-	sect.Vaddr = uint64(datsize)
-	typelink := ctxt.Syms.Lookup("runtime.typelink", 0)
-	typelink.Sect = sect
-	typelink.Type = sym.SRODATA
-	datsize += typelink.Size
-	checkdatsize(ctxt, datsize, sym.STYPELINK)
-	sect.Length = uint64(datsize) - sect.Vaddr
-
-	/* itablink */
-	sect = addrelrosection(".itablink")
-	sect.Align = dataMaxAlign[sym.SITABLINK]
-	datsize = Rnd(datsize, int64(sect.Align))
-	sect.Vaddr = uint64(datsize)
-	ctxt.Syms.Lookup("runtime.itablink", 0).Sect = sect
-	ctxt.Syms.Lookup("runtime.eitablink", 0).Sect = sect
-	for _, s := range data[sym.SITABLINK] {
-		datsize = aligndatsize(datsize, s)
-		s.Sect = sect
-		s.Type = sym.SRODATA
-		s.Value = int64(uint64(datsize) - sect.Vaddr)
-		datsize += s.Size
-	}
-	checkdatsize(ctxt, datsize, sym.SITABLINK)
-	sect.Length = uint64(datsize) - sect.Vaddr
-	if ctxt.HeadType == objabi.Haix {
-		// Store .itablink size because its symbols are wrapped
-		// under an outer symbol: runtime.itablink.
-		xcoffUpdateOuterSize(ctxt, int64(sect.Length), sym.SITABLINK)
-	}
-
-	/* gosymtab */
-	sect = addrelrosection(".gosymtab")
-	sect.Align = dataMaxAlign[sym.SSYMTAB]
-	datsize = Rnd(datsize, int64(sect.Align))
-	sect.Vaddr = uint64(datsize)
-	ctxt.Syms.Lookup("runtime.symtab", 0).Sect = sect
-	ctxt.Syms.Lookup("runtime.esymtab", 0).Sect = sect
-	for _, s := range data[sym.SSYMTAB] {
-		datsize = aligndatsize(datsize, s)
-		s.Sect = sect
-		s.Type = sym.SRODATA
-		s.Value = int64(uint64(datsize) - sect.Vaddr)
-		datsize += s.Size
-	}
-	checkdatsize(ctxt, datsize, sym.SSYMTAB)
-	sect.Length = uint64(datsize) - sect.Vaddr
-
-	/* gopclntab */
-	sect = addrelrosection(".gopclntab")
-	sect.Align = dataMaxAlign[sym.SPCLNTAB]
-	datsize = Rnd(datsize, int64(sect.Align))
-	sect.Vaddr = uint64(datsize)
-	ctxt.Syms.Lookup("runtime.pclntab", 0).Sect = sect
-	ctxt.Syms.Lookup("runtime.epclntab", 0).Sect = sect
-	for _, s := range data[sym.SPCLNTAB] {
-		datsize = aligndatsize(datsize, s)
-		s.Sect = sect
-		s.Type = sym.SRODATA
-		s.Value = int64(uint64(datsize) - sect.Vaddr)
-		datsize += s.Size
-	}
-	checkdatsize(ctxt, datsize, sym.SRODATA)
-	sect.Length = uint64(datsize) - sect.Vaddr
-
-	// 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
-	if datsize != int64(uint32(datsize)) {
-		Errorf(nil, "read-only data segment too large: %d", datsize)
-	}
-
-	for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ {
-		datap = append(datap, data[symn]...)
-	}
-
-	dwarfGenerateDebugSyms(ctxt)
-
-	var i int
-	for ; i < len(dwarfp); i++ {
-		s := dwarfp[i]
-		if s.Type != sym.SDWARFSECT {
-			break
-		}
-
-		sect = addsection(ctxt.Arch, &Segdwarf, s.Name, 04)
-		sect.Align = 1
-		datsize = Rnd(datsize, int64(sect.Align))
-		sect.Vaddr = uint64(datsize)
-		s.Sect = sect
-		s.Type = sym.SRODATA
-		s.Value = int64(uint64(datsize) - sect.Vaddr)
-		datsize += s.Size
-		sect.Length = uint64(datsize) - sect.Vaddr
-	}
-	checkdatsize(ctxt, datsize, sym.SDWARFSECT)
-
-	for i < len(dwarfp) {
-		curType := dwarfp[i].Type
-		var sect *sym.Section
-		switch curType {
-		case sym.SDWARFINFO:
-			sect = addsection(ctxt.Arch, &Segdwarf, ".debug_info", 04)
-		case sym.SDWARFRANGE:
-			sect = addsection(ctxt.Arch, &Segdwarf, ".debug_ranges", 04)
-		case sym.SDWARFLOC:
-			sect = addsection(ctxt.Arch, &Segdwarf, ".debug_loc", 04)
-		default:
-			// Error is unrecoverable, so panic.
-			panic(fmt.Sprintf("unknown DWARF section %v", curType))
-		}
-
-		sect.Align = 1
-		datsize = Rnd(datsize, int64(sect.Align))
-		sect.Vaddr = uint64(datsize)
-		for ; i < len(dwarfp); i++ {
-			s := dwarfp[i]
-			if s.Type != curType {
-				break
-			}
-			s.Sect = sect
-			s.Type = sym.SRODATA
-			s.Value = int64(uint64(datsize) - sect.Vaddr)
-			s.Attr |= sym.AttrLocal
-			datsize += s.Size
-
-			if ctxt.HeadType == objabi.Haix && curType == sym.SDWARFLOC {
-				// Update the size of .debug_loc for this symbol's
-				// package.
-				addDwsectCUSize(".debug_loc", s.File, uint64(s.Size))
-			}
-		}
-		sect.Length = uint64(datsize) - sect.Vaddr
-		checkdatsize(ctxt, datsize, curType)
-	}
-
-	/* number the sections */
-	n := int32(1)
-
-	for _, sect := range Segtext.Sections {
-		sect.Extnum = int16(n)
-		n++
-	}
-	for _, sect := range Segrodata.Sections {
-		sect.Extnum = int16(n)
-		n++
-	}
-	for _, sect := range Segrelrodata.Sections {
-		sect.Extnum = int16(n)
-		n++
-	}
-	for _, sect := range Segdata.Sections {
-		sect.Extnum = int16(n)
-		n++
-	}
-	for _, sect := range Segdwarf.Sections {
-		sect.Extnum = int16(n)
-		n++
-	}
-}
-
-func dodataSect(ctxt *Link, symn sym.SymKind, syms []*sym.Symbol) (result []*sym.Symbol, maxAlign int32) {
-	if ctxt.HeadType == objabi.Hdarwin {
-		// Some symbols may no longer belong in syms
-		// due to movement in machosymorder.
-		newSyms := make([]*sym.Symbol, 0, len(syms))
-		for _, s := range syms {
-			if s.Type == symn {
-				newSyms = append(newSyms, s)
-			}
-		}
-		syms = newSyms
-	}
-
-	var head, tail *sym.Symbol
-	symsSort := make([]dataSortKey, 0, len(syms))
-	for _, s := range syms {
-		if s.Attr.OnList() {
-			log.Fatalf("symbol %s listed multiple times", s.Name)
-		}
-		s.Attr |= sym.AttrOnList
-		switch {
-		case s.Size < int64(len(s.P)):
-			Errorf(s, "initialize bounds (%d < %d)", s.Size, len(s.P))
-		case s.Size < 0:
-			Errorf(s, "negative size (%d bytes)", s.Size)
-		case s.Size > cutoff:
-			Errorf(s, "symbol too large (%d bytes)", s.Size)
-		}
-
-		// If the usually-special section-marker symbols are being laid
-		// out as regular symbols, put them either at the beginning or
-		// end of their section.
-		if (ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
-			switch s.Name {
-			case "runtime.text", "runtime.bss", "runtime.data", "runtime.types", "runtime.rodata":
-				head = s
-				continue
-			case "runtime.etext", "runtime.ebss", "runtime.edata", "runtime.etypes", "runtime.erodata":
-				tail = s
-				continue
-			}
-		}
-
-		key := dataSortKey{
-			size: s.Size,
-			name: s.Name,
-			sym:  s,
-		}
-
-		switch s.Type {
-		case sym.SELFGOT:
-			// For ppc64, we want to interleave the .got and .toc sections
-			// from input files. Both are type sym.SELFGOT, so in that case
-			// we skip size comparison and fall through to the name
-			// comparison (conveniently, .got sorts before .toc).
-			key.size = 0
-		}
-
-		symsSort = append(symsSort, key)
-	}
-
-	sort.Sort(bySizeAndName(symsSort))
-
-	off := 0
-	if head != nil {
-		syms[0] = head
-		off++
-	}
-	for i, symSort := range symsSort {
-		syms[i+off] = symSort.sym
-		align := symalign(symSort.sym)
-		if maxAlign < align {
-			maxAlign = align
-		}
-	}
-	if tail != nil {
-		syms[len(syms)-1] = tail
-	}
-
-	if ctxt.IsELF && symn == sym.SELFROSECT {
-		// Make .rela and .rela.plt contiguous, the ELF ABI requires this
-		// and Solaris actually cares.
-		reli, plti := -1, -1
-		for i, s := range syms {
-			switch s.Name {
-			case ".rel.plt", ".rela.plt":
-				plti = i
-			case ".rel", ".rela":
-				reli = i
-			}
-		}
-		if reli >= 0 && plti >= 0 && plti != reli+1 {
-			var first, second int
-			if plti > reli {
-				first, second = reli, plti
-			} else {
-				first, second = plti, reli
-			}
-			rel, plt := syms[reli], syms[plti]
-			copy(syms[first+2:], syms[first+1:second])
-			syms[first+0] = rel
-			syms[first+1] = plt
-
-			// Make sure alignment doesn't introduce a gap.
-			// Setting the alignment explicitly prevents
-			// symalign from basing it on the size and
-			// getting it wrong.
-			rel.Align = int32(ctxt.Arch.RegSize)
-			plt.Align = int32(ctxt.Arch.RegSize)
-		}
-	}
-
-	return syms, maxAlign
-}
-
-// Add buildid to beginning of text segment, on non-ELF systems.
-// Non-ELF binary formats are not always flexible enough to
-// give us a place to put the Go build ID. On those systems, we put it
-// at the very beginning of the text segment.
-// This ``header'' is read by cmd/go.
-func (ctxt *Link) textbuildid() {
-	if ctxt.IsELF || ctxt.BuildMode == BuildModePlugin || *flagBuildid == "" {
-		return
-	}
-
-	s := ctxt.Syms.Lookup("go.buildid", 0)
-	s.Attr |= sym.AttrReachable
-	// The \xff is invalid UTF-8, meant to make it less likely
-	// to find one of these accidentally.
-	data := "\xff Go build ID: " + strconv.Quote(*flagBuildid) + "\n \xff"
-	s.Type = sym.STEXT
-	s.P = []byte(data)
-	s.Size = int64(len(s.P))
-
-	ctxt.Textp = append(ctxt.Textp, nil)
-	copy(ctxt.Textp[1:], ctxt.Textp)
-	ctxt.Textp[0] = s
-}
-
-func (ctxt *Link) buildinfo() {
-	if ctxt.linkShared || ctxt.BuildMode == BuildModePlugin {
-		// -linkshared and -buildmode=plugin get confused
-		// about the relocations in go.buildinfo
-		// pointing at the other data sections.
-		// The version information is only available in executables.
-		return
-	}
-
-	s := ctxt.Syms.Lookup(".go.buildinfo", 0)
-	s.Attr |= sym.AttrReachable
-	s.Type = sym.SBUILDINFO
-	s.Align = 16
-	// The \xff is invalid UTF-8, meant to make it less likely
-	// to find one of these accidentally.
-	const prefix = "\xff Go buildinf:" // 14 bytes, plus 2 data bytes filled in below
-	data := make([]byte, 32)
-	copy(data, prefix)
-	data[len(prefix)] = byte(ctxt.Arch.PtrSize)
-	data[len(prefix)+1] = 0
-	if ctxt.Arch.ByteOrder == binary.BigEndian {
-		data[len(prefix)+1] = 1
-	}
-	s.P = data
-	s.Size = int64(len(s.P))
-	s1 := ctxt.Syms.Lookup("runtime.buildVersion", 0)
-	s2 := ctxt.Syms.Lookup("runtime.modinfo", 0)
-	s.R = []sym.Reloc{
-		{Off: 16, Siz: uint8(ctxt.Arch.PtrSize), Type: objabi.R_ADDR, Sym: s1},
-		{Off: 16 + int32(ctxt.Arch.PtrSize), Siz: uint8(ctxt.Arch.PtrSize), Type: objabi.R_ADDR, Sym: s2},
-	}
-}
-
-// assign addresses to text
-func (ctxt *Link) textaddress() {
-	addsection(ctxt.Arch, &Segtext, ".text", 05)
-
-	// Assign PCs in text segment.
-	// Could parallelize, by assigning to text
-	// and then letting threads copy down, but probably not worth it.
-	sect := Segtext.Sections[0]
-
-	sect.Align = int32(Funcalign)
-
-	text := ctxt.Syms.Lookup("runtime.text", 0)
-	text.Sect = sect
-	if ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal {
-		// Setting runtime.text has a real symbol prevents ld to
-		// change its base address resulting in wrong offsets for
-		// reflect methods.
-		text.Align = sect.Align
-		text.Size = 0x8
-	}
-
-	if (ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
-		etext := ctxt.Syms.Lookup("runtime.etext", 0)
-		etext.Sect = sect
-
-		ctxt.Textp = append(ctxt.Textp, etext, nil)
-		copy(ctxt.Textp[1:], ctxt.Textp)
-		ctxt.Textp[0] = text
-	}
-
-	va := uint64(*FlagTextAddr)
-	n := 1
-	sect.Vaddr = va
-	ntramps := 0
-	for _, s := range ctxt.Textp {
-		sect, n, va = assignAddress(ctxt, sect, n, s, va, false)
-
-		trampoline(ctxt, s) // resolve jumps, may add trampolines if jump too far
-
-		// lay down trampolines after each function
-		for ; ntramps < len(ctxt.tramps); ntramps++ {
-			tramp := ctxt.tramps[ntramps]
-			if ctxt.HeadType == objabi.Haix && strings.HasPrefix(tramp.Name, "runtime.text.") {
-				// Already set in assignAddress
-				continue
-			}
-			sect, n, va = assignAddress(ctxt, sect, n, tramp, va, true)
-		}
-	}
-
-	sect.Length = va - sect.Vaddr
-	ctxt.Syms.Lookup("runtime.etext", 0).Sect = sect
-
-	// merge tramps into Textp, keeping Textp in address order
-	if ntramps != 0 {
-		newtextp := make([]*sym.Symbol, 0, len(ctxt.Textp)+ntramps)
-		i := 0
-		for _, s := range ctxt.Textp {
-			for ; i < ntramps && ctxt.tramps[i].Value < s.Value; i++ {
-				newtextp = append(newtextp, ctxt.tramps[i])
-			}
-			newtextp = append(newtextp, s)
-		}
-		newtextp = append(newtextp, ctxt.tramps[i:ntramps]...)
-
-		ctxt.Textp = newtextp
-	}
-}
-
-// assigns address for a text symbol, returns (possibly new) section, its number, and the address
-// Note: once we have trampoline insertion support for external linking, this function
-// will not need to create new text sections, and so no need to return sect and n.
-func assignAddress(ctxt *Link, sect *sym.Section, n int, s *sym.Symbol, va uint64, isTramp bool) (*sym.Section, int, uint64) {
-	if thearch.AssignAddress != nil {
-		return thearch.AssignAddress(ctxt, sect, n, s, va, isTramp)
-	}
-
-	s.Sect = sect
-	if s.Attr.SubSymbol() {
-		return sect, n, va
-	}
-	if s.Align != 0 {
-		va = uint64(Rnd(int64(va), int64(s.Align)))
-	} else {
-		va = uint64(Rnd(int64(va), int64(Funcalign)))
-	}
-
-	funcsize := uint64(MINFUNC) // spacing required for findfunctab
-	if s.Size > MINFUNC {
-		funcsize = uint64(s.Size)
-	}
-
-	if sect.Align < s.Align {
-		sect.Align = s.Align
-	}
-
-	// On ppc64x a text section should not be larger than 2^26 bytes due to the size of
-	// call target offset field in the bl instruction.  Splitting into smaller text
-	// sections smaller than this limit allows the GNU linker to modify the long calls
-	// appropriately.  The limit allows for the space needed for tables inserted by the linker.
-
-	// If this function doesn't fit in the current text section, then create a new one.
-
-	// Only break at outermost syms.
-
-	if ctxt.Arch.InFamily(sys.PPC64) && s.Outer == nil && ctxt.LinkMode == LinkExternal && va-sect.Vaddr+funcsize+maxSizeTrampolinesPPC64(s, isTramp) > 0x1c00000 {
-		// Set the length for the previous text section
-		sect.Length = va - sect.Vaddr
-
-		// Create new section, set the starting Vaddr
-		sect = addsection(ctxt.Arch, &Segtext, ".text", 05)
-		sect.Vaddr = va
-		s.Sect = sect
-
-		// Create a symbol for the start of the secondary text sections
-		ntext := ctxt.Syms.Lookup(fmt.Sprintf("runtime.text.%d", n), 0)
-		ntext.Sect = sect
-		if ctxt.HeadType == objabi.Haix {
-			// runtime.text.X must be a real symbol on AIX.
-			// Assign its address directly in order to be the
-			// first symbol of this new section.
-			ntext.Type = sym.STEXT
-			ntext.Size = int64(MINFUNC)
-			ntext.Attr |= sym.AttrReachable
-			ntext.Attr |= sym.AttrOnList
-			ctxt.tramps = append(ctxt.tramps, ntext)
-
-			ntext.Value = int64(va)
-			va += uint64(ntext.Size)
-
-			if s.Align != 0 {
-				va = uint64(Rnd(int64(va), int64(s.Align)))
-			} else {
-				va = uint64(Rnd(int64(va), int64(Funcalign)))
-			}
-		}
-		n++
-	}
-
-	s.Value = 0
-	for sub := s; sub != nil; sub = sub.Sub {
-		sub.Value += int64(va)
-	}
-
-	va += funcsize
-
-	return sect, n, va
-}
-
-// address assigns virtual addresses to all segments and sections and
-// returns all segments in file order.
-func (ctxt *Link) address() []*sym.Segment {
-	var order []*sym.Segment // Layout order
-
-	va := uint64(*FlagTextAddr)
-	order = append(order, &Segtext)
-	Segtext.Rwx = 05
-	Segtext.Vaddr = va
-	for _, s := range Segtext.Sections {
-		va = uint64(Rnd(int64(va), int64(s.Align)))
-		s.Vaddr = va
-		va += s.Length
-	}
-
-	Segtext.Length = va - uint64(*FlagTextAddr)
-
-	if len(Segrodata.Sections) > 0 {
-		// align to page boundary so as not to mix
-		// rodata and executable text.
-		//
-		// Note: gold or GNU ld will reduce the size of the executable
-		// file by arranging for the relro segment to end at a page
-		// boundary, and overlap the end of the text segment with the
-		// start of the relro segment in the file.  The PT_LOAD segments
-		// will be such that the last page of the text segment will be
-		// mapped twice, once r-x and once starting out rw- and, after
-		// relocation processing, changed to r--.
-		//
-		// Ideally the last page of the text segment would not be
-		// writable even for this short period.
-		va = uint64(Rnd(int64(va), int64(*FlagRound)))
-
-		order = append(order, &Segrodata)
-		Segrodata.Rwx = 04
-		Segrodata.Vaddr = va
-		for _, s := range Segrodata.Sections {
-			va = uint64(Rnd(int64(va), int64(s.Align)))
-			s.Vaddr = va
-			va += s.Length
-		}
-
-		Segrodata.Length = va - Segrodata.Vaddr
-	}
-	if len(Segrelrodata.Sections) > 0 {
-		// align to page boundary so as not to mix
-		// rodata, rel-ro data, and executable text.
-		va = uint64(Rnd(int64(va), int64(*FlagRound)))
-		if ctxt.HeadType == objabi.Haix {
-			// Relro data are inside data segment on AIX.
-			va += uint64(XCOFFDATABASE) - uint64(XCOFFTEXTBASE)
-		}
-
-		order = append(order, &Segrelrodata)
-		Segrelrodata.Rwx = 06
-		Segrelrodata.Vaddr = va
-		for _, s := range Segrelrodata.Sections {
-			va = uint64(Rnd(int64(va), int64(s.Align)))
-			s.Vaddr = va
-			va += s.Length
-		}
-
-		Segrelrodata.Length = va - Segrelrodata.Vaddr
-	}
-
-	va = uint64(Rnd(int64(va), int64(*FlagRound)))
-	if ctxt.HeadType == objabi.Haix && len(Segrelrodata.Sections) == 0 {
-		// Data sections are moved to an unreachable segment
-		// to ensure that they are position-independent.
-		// Already done if relro sections exist.
-		va += uint64(XCOFFDATABASE) - uint64(XCOFFTEXTBASE)
-	}
-	order = append(order, &Segdata)
-	Segdata.Rwx = 06
-	Segdata.Vaddr = va
-	var data *sym.Section
-	var noptr *sym.Section
-	var bss *sym.Section
-	var noptrbss *sym.Section
-	for i, s := range Segdata.Sections {
-		if (ctxt.IsELF || ctxt.HeadType == objabi.Haix) && s.Name == ".tbss" {
-			continue
-		}
-		vlen := int64(s.Length)
-		if i+1 < len(Segdata.Sections) && !((ctxt.IsELF || ctxt.HeadType == objabi.Haix) && Segdata.Sections[i+1].Name == ".tbss") {
-			vlen = int64(Segdata.Sections[i+1].Vaddr - s.Vaddr)
-		}
-		s.Vaddr = va
-		va += uint64(vlen)
-		Segdata.Length = va - Segdata.Vaddr
-		if s.Name == ".data" {
-			data = s
-		}
-		if s.Name == ".noptrdata" {
-			noptr = s
-		}
-		if s.Name == ".bss" {
-			bss = s
-		}
-		if s.Name == ".noptrbss" {
-			noptrbss = s
-		}
-	}
-
-	// Assign Segdata's Filelen omitting the BSS. We do this here
-	// simply because right now we know where the BSS starts.
-	Segdata.Filelen = bss.Vaddr - Segdata.Vaddr
-
-	va = uint64(Rnd(int64(va), int64(*FlagRound)))
-	order = append(order, &Segdwarf)
-	Segdwarf.Rwx = 06
-	Segdwarf.Vaddr = va
-	for i, s := range Segdwarf.Sections {
-		vlen := int64(s.Length)
-		if i+1 < len(Segdwarf.Sections) {
-			vlen = int64(Segdwarf.Sections[i+1].Vaddr - s.Vaddr)
-		}
-		s.Vaddr = va
-		va += uint64(vlen)
-		if ctxt.HeadType == objabi.Hwindows {
-			va = uint64(Rnd(int64(va), PEFILEALIGN))
-		}
-		Segdwarf.Length = va - Segdwarf.Vaddr
-	}
-
-	var (
-		text     = Segtext.Sections[0]
-		rodata   = ctxt.Syms.Lookup("runtime.rodata", 0).Sect
-		itablink = ctxt.Syms.Lookup("runtime.itablink", 0).Sect
-		symtab   = ctxt.Syms.Lookup("runtime.symtab", 0).Sect
-		pclntab  = ctxt.Syms.Lookup("runtime.pclntab", 0).Sect
-		types    = ctxt.Syms.Lookup("runtime.types", 0).Sect
-	)
-	lasttext := text
-	// Could be multiple .text sections
-	for _, sect := range Segtext.Sections {
-		if sect.Name == ".text" {
-			lasttext = sect
-		}
-	}
-
-	for _, s := range datap {
-		if s.Sect != nil {
-			s.Value += int64(s.Sect.Vaddr)
-		}
-		for sub := s.Sub; sub != nil; sub = sub.Sub {
-			sub.Value += s.Value
-		}
-	}
-
-	for _, s := range dwarfp {
-		if s.Sect != nil {
-			s.Value += int64(s.Sect.Vaddr)
-		}
-		for sub := s.Sub; sub != nil; sub = sub.Sub {
-			sub.Value += s.Value
-		}
-	}
-
-	if ctxt.BuildMode == BuildModeShared {
-		s := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
-		sectSym := ctxt.Syms.Lookup(".note.go.abihash", 0)
-		s.Sect = sectSym.Sect
-		s.Value = int64(sectSym.Sect.Vaddr + 16)
-	}
-
-	ctxt.xdefine("runtime.text", sym.STEXT, int64(text.Vaddr))
-	ctxt.xdefine("runtime.etext", sym.STEXT, int64(lasttext.Vaddr+lasttext.Length))
-
-	// If there are multiple text sections, create runtime.text.n for
-	// their section Vaddr, using n for index
-	n := 1
-	for _, sect := range Segtext.Sections[1:] {
-		if sect.Name != ".text" {
-			break
-		}
-		symname := fmt.Sprintf("runtime.text.%d", n)
-		if ctxt.HeadType != objabi.Haix || ctxt.LinkMode != LinkExternal {
-			// Addresses are already set on AIX with external linker
-			// because these symbols are part of their sections.
-			ctxt.xdefine(symname, sym.STEXT, int64(sect.Vaddr))
-		}
-		n++
-	}
-
-	ctxt.xdefine("runtime.rodata", sym.SRODATA, int64(rodata.Vaddr))
-	ctxt.xdefine("runtime.erodata", sym.SRODATA, int64(rodata.Vaddr+rodata.Length))
-	ctxt.xdefine("runtime.types", sym.SRODATA, int64(types.Vaddr))
-	ctxt.xdefine("runtime.etypes", sym.SRODATA, int64(types.Vaddr+types.Length))
-	ctxt.xdefine("runtime.itablink", sym.SRODATA, int64(itablink.Vaddr))
-	ctxt.xdefine("runtime.eitablink", sym.SRODATA, int64(itablink.Vaddr+itablink.Length))
-
-	s := ctxt.Syms.Lookup("runtime.gcdata", 0)
-	s.Attr |= sym.AttrLocal
-	ctxt.xdefine("runtime.egcdata", sym.SRODATA, Symaddr(s)+s.Size)
-	ctxt.Syms.Lookup("runtime.egcdata", 0).Sect = s.Sect
-
-	s = ctxt.Syms.Lookup("runtime.gcbss", 0)
-	s.Attr |= sym.AttrLocal
-	ctxt.xdefine("runtime.egcbss", sym.SRODATA, Symaddr(s)+s.Size)
-	ctxt.Syms.Lookup("runtime.egcbss", 0).Sect = s.Sect
-
-	ctxt.xdefine("runtime.symtab", sym.SRODATA, int64(symtab.Vaddr))
-	ctxt.xdefine("runtime.esymtab", sym.SRODATA, int64(symtab.Vaddr+symtab.Length))
-	ctxt.xdefine("runtime.pclntab", sym.SRODATA, int64(pclntab.Vaddr))
-	ctxt.xdefine("runtime.epclntab", sym.SRODATA, int64(pclntab.Vaddr+pclntab.Length))
-	ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr))
-	ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr+noptr.Length))
-	ctxt.xdefine("runtime.bss", sym.SBSS, int64(bss.Vaddr))
-	ctxt.xdefine("runtime.ebss", sym.SBSS, int64(bss.Vaddr+bss.Length))
-	ctxt.xdefine("runtime.data", sym.SDATA, int64(data.Vaddr))
-	ctxt.xdefine("runtime.edata", sym.SDATA, int64(data.Vaddr+data.Length))
-	ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr))
-	ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length))
-	ctxt.xdefine("runtime.end", sym.SBSS, int64(Segdata.Vaddr+Segdata.Length))
-
-	return order
-}
-
-// layout assigns file offsets and lengths to the segments in order.
-// Returns the file size containing all the segments.
-func (ctxt *Link) layout(order []*sym.Segment) uint64 {
-	var prev *sym.Segment
-	for _, seg := range order {
-		if prev == nil {
-			seg.Fileoff = uint64(HEADR)
-		} else {
-			switch ctxt.HeadType {
-			default:
-				// Assuming the previous segment was
-				// aligned, the following rounding
-				// should ensure that this segment's
-				// VA ≡ Fileoff mod FlagRound.
-				seg.Fileoff = uint64(Rnd(int64(prev.Fileoff+prev.Filelen), int64(*FlagRound)))
-				if seg.Vaddr%uint64(*FlagRound) != seg.Fileoff%uint64(*FlagRound) {
-					Exitf("bad segment rounding (Vaddr=%#x Fileoff=%#x FlagRound=%#x)", seg.Vaddr, seg.Fileoff, *FlagRound)
-				}
-			case objabi.Hwindows:
-				seg.Fileoff = prev.Fileoff + uint64(Rnd(int64(prev.Filelen), PEFILEALIGN))
-			case objabi.Hplan9:
-				seg.Fileoff = prev.Fileoff + prev.Filelen
-			}
-		}
-		if seg != &Segdata {
-			// Link.address already set Segdata.Filelen to
-			// account for BSS.
-			seg.Filelen = seg.Length
-		}
-		prev = seg
-	}
-	return prev.Fileoff + prev.Filelen
-}
-
-// add a trampoline with symbol s (to be laid down after the current function)
-func (ctxt *Link) AddTramp(s *sym.Symbol) {
-	s.Type = sym.STEXT
-	s.Attr |= sym.AttrReachable
-	s.Attr |= sym.AttrOnList
-	ctxt.tramps = append(ctxt.tramps, s)
-	if *FlagDebugTramp > 0 && ctxt.Debugvlog > 0 {
-		ctxt.Logf("trampoline %s inserted\n", s)
-	}
-}
-
-// compressSyms compresses syms and returns the contents of the
-// compressed section. If the section would get larger, it returns nil.
-func compressSyms(ctxt *Link, syms []*sym.Symbol) []byte {
-	var total int64
-	for _, sym := range syms {
-		total += sym.Size
-	}
-
-	var buf bytes.Buffer
-	buf.Write([]byte("ZLIB"))
-	var sizeBytes [8]byte
-	binary.BigEndian.PutUint64(sizeBytes[:], uint64(total))
-	buf.Write(sizeBytes[:])
-
-	// Using zlib.BestSpeed achieves very nearly the same
-	// compression levels of zlib.DefaultCompression, but takes
-	// substantially less time. This is important because DWARF
-	// compression can be a significant fraction of link time.
-	z, err := zlib.NewWriterLevel(&buf, zlib.BestSpeed)
-	if err != nil {
-		log.Fatalf("NewWriterLevel failed: %s", err)
-	}
-	for _, s := range syms {
-		// s.P may be read-only. Apply relocations in a
-		// temporary buffer, and immediately write it out.
-		oldP := s.P
-		wasReadOnly := s.Attr.ReadOnly()
-		if len(s.R) != 0 && wasReadOnly {
-			ctxt.relocbuf = append(ctxt.relocbuf[:0], s.P...)
-			s.P = ctxt.relocbuf
-			s.Attr.Set(sym.AttrReadOnly, false)
-		}
-		relocsym(ctxt, s)
-		if _, err := z.Write(s.P); err != nil {
-			log.Fatalf("compression failed: %s", err)
-		}
-		for i := s.Size - int64(len(s.P)); i > 0; {
-			b := zeros[:]
-			if i < int64(len(b)) {
-				b = b[:i]
-			}
-			n, err := z.Write(b)
-			if err != nil {
-				log.Fatalf("compression failed: %s", err)
-			}
-			i -= int64(n)
-		}
-		// Restore s.P if a temporary buffer was used. If compression
-		// is not beneficial, we'll go back to use the uncompressed
-		// contents, in which case we still need s.P.
-		if len(s.R) != 0 && wasReadOnly {
-			s.P = oldP
-			s.Attr.Set(sym.AttrReadOnly, wasReadOnly)
-			for i := range s.R {
-				s.R[i].Done = false
-			}
-		}
-	}
-	if err := z.Close(); err != nil {
-		log.Fatalf("compression failed: %s", err)
-	}
-	if int64(buf.Len()) >= total {
-		// Compression didn't save any space.
-		return nil
-	}
-	return buf.Bytes()
-}
diff --git a/src/cmd/oldlink/internal/ld/deadcode.go b/src/cmd/oldlink/internal/ld/deadcode.go
deleted file mode 100644
index 6a6813a..0000000
--- a/src/cmd/oldlink/internal/ld/deadcode.go
+++ /dev/null
@@ -1,409 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ld
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/sym"
-	"fmt"
-	"strings"
-	"unicode"
-)
-
-// deadcode marks all reachable symbols.
-//
-// The basis of the dead code elimination is a flood fill of symbols,
-// following their relocations, beginning at *flagEntrySymbol.
-//
-// This flood fill is wrapped in logic for pruning unused methods.
-// All methods are mentioned by relocations on their receiver's *rtype.
-// These relocations are specially defined as R_METHODOFF by the compiler
-// so we can detect and manipulated them here.
-//
-// There are three ways a method of a reachable type can be invoked:
-//
-//	1. direct call
-//	2. through a reachable interface type
-//	3. reflect.Value.Method (or MethodByName), or reflect.Type.Method
-//	   (or MethodByName)
-//
-// The first case is handled by the flood fill, a directly called method
-// is marked as reachable.
-//
-// The second case is handled by decomposing all reachable interface
-// types into method signatures. Each encountered method is compared
-// against the interface method signatures, if it matches it is marked
-// as reachable. This is extremely conservative, but easy and correct.
-//
-// The third case is handled by looking to see if any of:
-//	- reflect.Value.Method or MethodByName is reachable
-// 	- reflect.Type.Method or MethodByName is called (through the
-// 	  REFLECTMETHOD attribute marked by the compiler).
-// If any of these happen, all bets are off and all exported methods
-// of reachable types are marked reachable.
-//
-// Any unreached text symbols are removed from ctxt.Textp.
-func deadcode(ctxt *Link) {
-	if ctxt.Debugvlog != 0 {
-		ctxt.Logf("deadcode\n")
-	}
-
-	if *flagNewobj {
-		deadcode2(ctxt)
-		return
-	}
-
-	d := &deadcodepass{
-		ctxt:        ctxt,
-		ifaceMethod: make(map[methodsig]bool),
-	}
-
-	// First, flood fill any symbols directly reachable in the call
-	// graph from *flagEntrySymbol. Ignore all methods not directly called.
-	d.init()
-	d.flood()
-
-	methSym := ctxt.Syms.ROLookup("reflect.Value.Method", sym.SymVerABIInternal)
-	methByNameSym := ctxt.Syms.ROLookup("reflect.Value.MethodByName", sym.SymVerABIInternal)
-	reflectSeen := false
-
-	if ctxt.DynlinkingGo() {
-		// Exported methods may satisfy interfaces we don't know
-		// about yet when dynamically linking.
-		reflectSeen = true
-	}
-
-	for {
-		if !reflectSeen {
-			if d.reflectMethod || (methSym != nil && methSym.Attr.Reachable()) || (methByNameSym != nil && methByNameSym.Attr.Reachable()) {
-				// Methods might be called via reflection. Give up on
-				// static analysis, mark all exported methods of
-				// all reachable types as reachable.
-				reflectSeen = true
-			}
-		}
-
-		// Mark all methods that could satisfy a discovered
-		// interface as reachable. We recheck old marked interfaces
-		// as new types (with new methods) may have been discovered
-		// in the last pass.
-		var rem []methodref
-		for _, m := range d.markableMethods {
-			if (reflectSeen && m.isExported()) || d.ifaceMethod[m.m] {
-				d.markMethod(m)
-			} else {
-				rem = append(rem, m)
-			}
-		}
-		d.markableMethods = rem
-
-		if len(d.markQueue) == 0 {
-			// No new work was discovered. Done.
-			break
-		}
-		d.flood()
-	}
-
-	// Remove all remaining unreached R_METHODOFF relocations.
-	for _, m := range d.markableMethods {
-		for _, r := range m.r {
-			d.cleanupReloc(r)
-		}
-	}
-
-	if ctxt.BuildMode != BuildModeShared {
-		// Keep a itablink if the symbol it points at is being kept.
-		// (When BuildModeShared, always keep itablinks.)
-		for _, s := range ctxt.Syms.Allsym {
-			if strings.HasPrefix(s.Name, "go.itablink.") {
-				s.Attr.Set(sym.AttrReachable, len(s.R) == 1 && s.R[0].Sym.Attr.Reachable())
-			}
-		}
-	}
-
-	addToTextp(ctxt)
-}
-
-func addToTextp(ctxt *Link) {
-	// Remove dead text but keep file information (z symbols).
-	textp := []*sym.Symbol{}
-	for _, s := range ctxt.Textp {
-		if s.Attr.Reachable() {
-			textp = append(textp, s)
-		}
-	}
-
-	// Put reachable text symbols into Textp.
-	// do it in postorder so that packages are laid down in dependency order
-	// internal first, then everything else
-	ctxt.Library = postorder(ctxt.Library)
-	for _, doInternal := range [2]bool{true, false} {
-		for _, lib := range ctxt.Library {
-			if isRuntimeDepPkg(lib.Pkg) != doInternal {
-				continue
-			}
-			libtextp := lib.Textp[:0]
-			for _, s := range lib.Textp {
-				if s.Attr.Reachable() {
-					textp = append(textp, s)
-					libtextp = append(libtextp, s)
-					if s.Unit != nil {
-						s.Unit.Textp = append(s.Unit.Textp, s)
-					}
-				}
-			}
-			for _, s := range lib.DupTextSyms {
-				if s.Attr.Reachable() && !s.Attr.OnList() {
-					textp = append(textp, s)
-					libtextp = append(libtextp, s)
-					if s.Unit != nil {
-						s.Unit.Textp = append(s.Unit.Textp, s)
-					}
-					s.Attr |= sym.AttrOnList
-					// dupok symbols may be defined in multiple packages. its
-					// associated package is chosen sort of arbitrarily (the
-					// first containing package that the linker loads). canonicalize
-					// it here to the package with which it will be laid down
-					// in text.
-					s.File = objabi.PathToPrefix(lib.Pkg)
-				}
-			}
-			lib.Textp = libtextp
-		}
-	}
-	ctxt.Textp = textp
-
-	if len(ctxt.Shlibs) > 0 {
-		// We might have overwritten some functions above (this tends to happen for the
-		// autogenerated type equality/hashing functions) and we don't want to generated
-		// pcln table entries for these any more so remove them from Textp.
-		textp := make([]*sym.Symbol, 0, len(ctxt.Textp))
-		for _, s := range ctxt.Textp {
-			if s.Type != sym.SDYNIMPORT {
-				textp = append(textp, s)
-			}
-		}
-		ctxt.Textp = textp
-	}
-}
-
-// methodref holds the relocations from a receiver type symbol to its
-// method. There are three relocations, one for each of the fields in
-// the reflect.method struct: mtyp, ifn, and tfn.
-type methodref struct {
-	m   methodsig
-	src *sym.Symbol   // receiver type symbol
-	r   [3]*sym.Reloc // R_METHODOFF relocations to fields of runtime.method
-}
-
-func (m methodref) ifn() *sym.Symbol { return m.r[1].Sym }
-
-func (m methodref) isExported() bool {
-	for _, r := range m.m {
-		return unicode.IsUpper(r)
-	}
-	panic("methodref has no signature")
-}
-
-// deadcodepass holds state for the deadcode flood fill.
-type deadcodepass struct {
-	ctxt            *Link
-	markQueue       []*sym.Symbol      // symbols to flood fill in next pass
-	ifaceMethod     map[methodsig]bool // methods declared in reached interfaces
-	markableMethods []methodref        // methods of reached types
-	reflectMethod   bool
-}
-
-func (d *deadcodepass) cleanupReloc(r *sym.Reloc) {
-	if r.Sym.Attr.Reachable() {
-		r.Type = objabi.R_ADDROFF
-	} else {
-		if d.ctxt.Debugvlog > 1 {
-			d.ctxt.Logf("removing method %s\n", r.Sym.Name)
-		}
-		r.Sym = nil
-		r.Siz = 0
-	}
-}
-
-// mark appends a symbol to the mark queue for flood filling.
-func (d *deadcodepass) mark(s, parent *sym.Symbol) {
-	if s == nil || s.Attr.Reachable() {
-		return
-	}
-	if s.Attr.ReflectMethod() {
-		d.reflectMethod = true
-	}
-	if *flagDumpDep {
-		p := "_"
-		if parent != nil {
-			p = parent.Name
-		}
-		fmt.Printf("%s -> %s\n", p, s.Name)
-	}
-	s.Attr |= sym.AttrReachable
-	if d.ctxt.Reachparent != nil {
-		d.ctxt.Reachparent[s] = parent
-	}
-	d.markQueue = append(d.markQueue, s)
-}
-
-// markMethod marks a method as reachable.
-func (d *deadcodepass) markMethod(m methodref) {
-	for _, r := range m.r {
-		d.mark(r.Sym, m.src)
-		r.Type = objabi.R_ADDROFF
-	}
-}
-
-// init marks all initial symbols as reachable.
-// In a typical binary, this is *flagEntrySymbol.
-func (d *deadcodepass) init() {
-	var names []string
-
-	if d.ctxt.BuildMode == BuildModeShared {
-		// Mark all symbols defined in this library as reachable when
-		// building a shared library.
-		for _, s := range d.ctxt.Syms.Allsym {
-			if s.Type != 0 && s.Type != sym.SDYNIMPORT {
-				d.mark(s, nil)
-			}
-		}
-	} else {
-		// In a normal binary, start at main.main and the init
-		// functions and mark what is reachable from there.
-
-		if d.ctxt.linkShared && (d.ctxt.BuildMode == BuildModeExe || d.ctxt.BuildMode == BuildModePIE) {
-			names = append(names, "main.main", "main..inittask")
-		} else {
-			// The external linker refers main symbol directly.
-			if d.ctxt.LinkMode == LinkExternal && (d.ctxt.BuildMode == BuildModeExe || d.ctxt.BuildMode == BuildModePIE) {
-				if d.ctxt.HeadType == objabi.Hwindows && d.ctxt.Arch.Family == sys.I386 {
-					*flagEntrySymbol = "_main"
-				} else {
-					*flagEntrySymbol = "main"
-				}
-			}
-			names = append(names, *flagEntrySymbol)
-			if d.ctxt.BuildMode == BuildModePlugin {
-				names = append(names, objabi.PathToPrefix(*flagPluginPath)+"..inittask", objabi.PathToPrefix(*flagPluginPath)+".main", "go.plugin.tabs")
-
-				// We don't keep the go.plugin.exports symbol,
-				// but we do keep the symbols it refers to.
-				exports := d.ctxt.Syms.ROLookup("go.plugin.exports", 0)
-				if exports != nil {
-					for i := range exports.R {
-						d.mark(exports.R[i].Sym, nil)
-					}
-				}
-			}
-		}
-		for _, s := range dynexp {
-			d.mark(s, nil)
-		}
-	}
-
-	for _, name := range names {
-		// Mark symbol as a data/ABI0 symbol.
-		d.mark(d.ctxt.Syms.ROLookup(name, 0), nil)
-		// Also mark any Go functions (internal ABI).
-		d.mark(d.ctxt.Syms.ROLookup(name, sym.SymVerABIInternal), nil)
-	}
-}
-
-// flood fills symbols reachable from the markQueue symbols.
-// As it goes, it collects methodref and interface method declarations.
-func (d *deadcodepass) flood() {
-	for len(d.markQueue) > 0 {
-		s := d.markQueue[0]
-		d.markQueue = d.markQueue[1:]
-		if s.Type == sym.STEXT {
-			if d.ctxt.Debugvlog > 1 {
-				d.ctxt.Logf("marktext %s\n", s.Name)
-			}
-		}
-
-		if strings.HasPrefix(s.Name, "type.") && s.Name[5] != '.' {
-			if len(s.P) == 0 {
-				// Probably a bug. The undefined symbol check
-				// later will give a better error than deadcode.
-				continue
-			}
-			if decodetypeKind(d.ctxt.Arch, s.P)&kindMask == kindInterface {
-				for _, sig := range decodeIfaceMethods(d.ctxt.Arch, s) {
-					if d.ctxt.Debugvlog > 1 {
-						d.ctxt.Logf("reached iface method: %s\n", sig)
-					}
-					d.ifaceMethod[sig] = true
-				}
-			}
-		}
-
-		mpos := 0 // 0-3, the R_METHODOFF relocs of runtime.uncommontype
-		var methods []methodref
-		for i := range s.R {
-			r := &s.R[i]
-			if r.Sym == nil {
-				continue
-			}
-			if r.Type == objabi.R_WEAKADDROFF {
-				// An R_WEAKADDROFF relocation is not reason
-				// enough to mark the pointed-to symbol as
-				// reachable.
-				continue
-			}
-			if r.Sym.Type == sym.SABIALIAS {
-				// Patch this relocation through the
-				// ABI alias before marking.
-				r.Sym = resolveABIAlias(r.Sym)
-			}
-			if r.Type != objabi.R_METHODOFF {
-				d.mark(r.Sym, s)
-				continue
-			}
-			// Collect rtype pointers to methods for
-			// later processing in deadcode.
-			if mpos == 0 {
-				m := methodref{src: s}
-				m.r[0] = r
-				methods = append(methods, m)
-			} else {
-				methods[len(methods)-1].r[mpos] = r
-			}
-			mpos++
-			if mpos == len(methodref{}.r) {
-				mpos = 0
-			}
-		}
-		if len(methods) > 0 {
-			// Decode runtime type information for type methods
-			// to help work out which methods can be called
-			// dynamically via interfaces.
-			methodsigs := decodetypeMethods(d.ctxt.Arch, s)
-			if len(methods) != len(methodsigs) {
-				panic(fmt.Sprintf("%q has %d method relocations for %d methods", s.Name, len(methods), len(methodsigs)))
-			}
-			for i, m := range methodsigs {
-				name := string(m)
-				name = name[:strings.Index(name, "(")]
-				if !strings.HasSuffix(methods[i].ifn().Name, name) {
-					panic(fmt.Sprintf("%q relocation for %q does not match method %q", s.Name, methods[i].ifn().Name, name))
-				}
-				methods[i].m = m
-			}
-			d.markableMethods = append(d.markableMethods, methods...)
-		}
-
-		if s.FuncInfo != nil {
-			for i := range s.FuncInfo.Funcdata {
-				d.mark(s.FuncInfo.Funcdata[i], s)
-			}
-		}
-		d.mark(s.Gotype, s)
-		d.mark(s.Sub, s)
-		d.mark(s.Outer, s)
-	}
-}
diff --git a/src/cmd/oldlink/internal/ld/deadcode2.go b/src/cmd/oldlink/internal/ld/deadcode2.go
deleted file mode 100644
index 82bfd60..0000000
--- a/src/cmd/oldlink/internal/ld/deadcode2.go
+++ /dev/null
@@ -1,441 +0,0 @@
-// Copyright 2019 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 ld
-
-import (
-	"bytes"
-	"cmd/internal/dwarf"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/loader"
-	"cmd/oldlink/internal/sym"
-	"container/heap"
-	"fmt"
-	"unicode"
-)
-
-var _ = fmt.Print
-
-type workQueue []loader.Sym
-
-// Implement container/heap.Interface.
-func (q *workQueue) Len() int           { return len(*q) }
-func (q *workQueue) Less(i, j int) bool { return (*q)[i] < (*q)[j] }
-func (q *workQueue) Swap(i, j int)      { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
-func (q *workQueue) Push(i interface{}) { *q = append(*q, i.(loader.Sym)) }
-func (q *workQueue) Pop() interface{}   { i := (*q)[len(*q)-1]; *q = (*q)[:len(*q)-1]; return i }
-
-// Functions for deadcode pass to use.
-// Deadcode pass should call push/pop, not Push/Pop.
-func (q *workQueue) push(i loader.Sym) { heap.Push(q, i) }
-func (q *workQueue) pop() loader.Sym   { return heap.Pop(q).(loader.Sym) }
-func (q *workQueue) empty() bool       { return len(*q) == 0 }
-
-type deadcodePass2 struct {
-	ctxt *Link
-	ldr  *loader.Loader
-	wq   workQueue
-	rtmp []loader.Reloc
-
-	ifaceMethod     map[methodsig]bool // methods declared in reached interfaces
-	markableMethods []methodref2       // methods of reached types
-	reflectSeen     bool               // whether we have seen a reflect method call
-}
-
-func (d *deadcodePass2) init() {
-	d.ldr.InitReachable()
-	d.ifaceMethod = make(map[methodsig]bool)
-	if d.ctxt.Reachparent != nil {
-		d.ldr.Reachparent = make([]loader.Sym, d.ldr.NSym())
-	}
-	heap.Init(&d.wq)
-
-	if d.ctxt.BuildMode == BuildModeShared {
-		// Mark all symbols defined in this library as reachable when
-		// building a shared library.
-		n := d.ldr.NDef()
-		for i := 1; i < n; i++ {
-			s := loader.Sym(i)
-			if !d.ldr.IsDup(s) {
-				d.mark(s, 0)
-			}
-		}
-		return
-	}
-
-	var names []string
-
-	// In a normal binary, start at main.main and the init
-	// functions and mark what is reachable from there.
-	if d.ctxt.linkShared && (d.ctxt.BuildMode == BuildModeExe || d.ctxt.BuildMode == BuildModePIE) {
-		names = append(names, "main.main", "main..inittask")
-	} else {
-		// The external linker refers main symbol directly.
-		if d.ctxt.LinkMode == LinkExternal && (d.ctxt.BuildMode == BuildModeExe || d.ctxt.BuildMode == BuildModePIE) {
-			if d.ctxt.HeadType == objabi.Hwindows && d.ctxt.Arch.Family == sys.I386 {
-				*flagEntrySymbol = "_main"
-			} else {
-				*flagEntrySymbol = "main"
-			}
-		}
-		names = append(names, *flagEntrySymbol)
-		if d.ctxt.BuildMode == BuildModePlugin {
-			names = append(names, objabi.PathToPrefix(*flagPluginPath)+"..inittask", objabi.PathToPrefix(*flagPluginPath)+".main", "go.plugin.tabs")
-
-			// We don't keep the go.plugin.exports symbol,
-			// but we do keep the symbols it refers to.
-			exportsIdx := d.ldr.Lookup("go.plugin.exports", 0)
-			if exportsIdx != 0 {
-				d.ReadRelocs(exportsIdx)
-				for i := 0; i < len(d.rtmp); i++ {
-					d.mark(d.rtmp[i].Sym, 0)
-				}
-			}
-		}
-	}
-
-	dynexpMap := d.ctxt.cgo_export_dynamic
-	if d.ctxt.LinkMode == LinkExternal {
-		dynexpMap = d.ctxt.cgo_export_static
-	}
-	for exp := range dynexpMap {
-		names = append(names, exp)
-	}
-
-	// DWARF constant DIE symbols are not referenced, but needed by
-	// the dwarf pass.
-	if !*FlagW {
-		for _, lib := range d.ctxt.Library {
-			names = append(names, dwarf.ConstInfoPrefix+lib.Pkg)
-		}
-	}
-
-	for _, name := range names {
-		// Mark symbol as a data/ABI0 symbol.
-		d.mark(d.ldr.Lookup(name, 0), 0)
-		// Also mark any Go functions (internal ABI).
-		d.mark(d.ldr.Lookup(name, sym.SymVerABIInternal), 0)
-	}
-}
-
-func (d *deadcodePass2) flood() {
-	symRelocs := []loader.Reloc{}
-	auxSyms := []loader.Sym{}
-	for !d.wq.empty() {
-		symIdx := d.wq.pop()
-
-		d.reflectSeen = d.reflectSeen || d.ldr.IsReflectMethod(symIdx)
-
-		relocs := d.ldr.Relocs(symIdx)
-		symRelocs = relocs.ReadAll(symRelocs)
-
-		if d.ldr.IsGoType(symIdx) {
-			p := d.ldr.Data(symIdx)
-			if len(p) != 0 && decodetypeKind(d.ctxt.Arch, p)&kindMask == kindInterface {
-				for _, sig := range d.decodeIfaceMethods2(d.ldr, d.ctxt.Arch, symIdx, symRelocs) {
-					if d.ctxt.Debugvlog > 1 {
-						d.ctxt.Logf("reached iface method: %s\n", sig)
-					}
-					d.ifaceMethod[sig] = true
-				}
-			}
-		}
-
-		var methods []methodref2
-		for i := 0; i < relocs.Count; i++ {
-			r := symRelocs[i]
-			if r.Type == objabi.R_WEAKADDROFF {
-				continue
-			}
-			if r.Type == objabi.R_METHODOFF {
-				if i+2 >= relocs.Count {
-					panic("expect three consecutive R_METHODOFF relocs")
-				}
-				methods = append(methods, methodref2{src: symIdx, r: i})
-				i += 2
-				continue
-			}
-			if r.Type == objabi.R_USETYPE {
-				// type symbol used for DWARF. we need to load the symbol but it may not
-				// be otherwise reachable in the program.
-				// do nothing for now as we still load all type symbols.
-				continue
-			}
-			d.mark(r.Sym, symIdx)
-		}
-		auxSyms = d.ldr.ReadAuxSyms(symIdx, auxSyms)
-		for i := 0; i < len(auxSyms); i++ {
-			d.mark(auxSyms[i], symIdx)
-		}
-		// Some host object symbols have an outer object, which acts like a
-		// "carrier" symbol, or it holds all the symbols for a particular
-		// section. We need to mark all "referenced" symbols from that carrier,
-		// so we make sure we're pulling in all outer symbols, and their sub
-		// symbols. This is not ideal, and these carrier/section symbols could
-		// be removed.
-		d.mark(d.ldr.OuterSym(symIdx), symIdx)
-		d.mark(d.ldr.SubSym(symIdx), symIdx)
-
-		if len(methods) != 0 {
-			// Decode runtime type information for type methods
-			// to help work out which methods can be called
-			// dynamically via interfaces.
-			methodsigs := d.decodetypeMethods2(d.ldr, d.ctxt.Arch, symIdx, symRelocs)
-			if len(methods) != len(methodsigs) {
-				panic(fmt.Sprintf("%q has %d method relocations for %d methods", d.ldr.SymName(symIdx), len(methods), len(methodsigs)))
-			}
-			for i, m := range methodsigs {
-				methods[i].m = m
-			}
-			d.markableMethods = append(d.markableMethods, methods...)
-		}
-	}
-}
-
-func (d *deadcodePass2) mark(symIdx, parent loader.Sym) {
-	if symIdx != 0 && !d.ldr.Reachable.Has(symIdx) {
-		d.wq.push(symIdx)
-		d.ldr.Reachable.Set(symIdx)
-		if d.ctxt.Reachparent != nil {
-			d.ldr.Reachparent[symIdx] = parent
-		}
-		if *flagDumpDep {
-			to := d.ldr.SymName(symIdx)
-			if to != "" {
-				from := "_"
-				if parent != 0 {
-					from = d.ldr.SymName(parent)
-				}
-				fmt.Printf("%s -> %s\n", from, to)
-			}
-		}
-	}
-}
-
-func (d *deadcodePass2) markMethod(m methodref2) {
-	d.ReadRelocs(m.src)
-	d.mark(d.rtmp[m.r].Sym, m.src)
-	d.mark(d.rtmp[m.r+1].Sym, m.src)
-	d.mark(d.rtmp[m.r+2].Sym, m.src)
-}
-
-func deadcode2(ctxt *Link) {
-	ldr := ctxt.loader
-	d := deadcodePass2{ctxt: ctxt, ldr: ldr}
-	d.init()
-	d.flood()
-
-	callSym := ldr.Lookup("reflect.Value.Call", sym.SymVerABIInternal)
-	methSym := ldr.Lookup("reflect.Value.Method", sym.SymVerABIInternal)
-	if ctxt.DynlinkingGo() {
-		// Exported methods may satisfy interfaces we don't know
-		// about yet when dynamically linking.
-		d.reflectSeen = true
-	}
-
-	for {
-		// Methods might be called via reflection. Give up on
-		// static analysis, mark all exported methods of
-		// all reachable types as reachable.
-		d.reflectSeen = d.reflectSeen || (callSym != 0 && ldr.Reachable.Has(callSym)) || (methSym != 0 && ldr.Reachable.Has(methSym))
-
-		// Mark all methods that could satisfy a discovered
-		// interface as reachable. We recheck old marked interfaces
-		// as new types (with new methods) may have been discovered
-		// in the last pass.
-		rem := d.markableMethods[:0]
-		for _, m := range d.markableMethods {
-			if (d.reflectSeen && m.isExported()) || d.ifaceMethod[m.m] {
-				d.markMethod(m)
-			} else {
-				rem = append(rem, m)
-			}
-		}
-		d.markableMethods = rem
-
-		if d.wq.empty() {
-			// No new work was discovered. Done.
-			break
-		}
-		d.flood()
-	}
-
-	n := ldr.NSym()
-
-	if ctxt.BuildMode != BuildModeShared {
-		// Keep a itablink if the symbol it points at is being kept.
-		// (When BuildModeShared, always keep itablinks.)
-		for i := 1; i < n; i++ {
-			s := loader.Sym(i)
-			if ldr.IsItabLink(s) {
-				relocs := ldr.Relocs(s)
-				if relocs.Count > 0 && ldr.Reachable.Has(relocs.At(0).Sym) {
-					ldr.Reachable.Set(s)
-				}
-			}
-		}
-	}
-}
-
-// methodref2 holds the relocations from a receiver type symbol to its
-// method. There are three relocations, one for each of the fields in
-// the reflect.method struct: mtyp, ifn, and tfn.
-type methodref2 struct {
-	m   methodsig
-	src loader.Sym // receiver type symbol
-	r   int        // the index of R_METHODOFF relocations
-}
-
-func (m methodref2) isExported() bool {
-	for _, r := range m.m {
-		return unicode.IsUpper(r)
-	}
-	panic("methodref has no signature")
-}
-
-// decodeMethodSig2 decodes an array of method signature information.
-// Each element of the array is size bytes. The first 4 bytes is a
-// nameOff for the method name, and the next 4 bytes is a typeOff for
-// the function type.
-//
-// Conveniently this is the layout of both runtime.method and runtime.imethod.
-func (d *deadcodePass2) decodeMethodSig2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, symRelocs []loader.Reloc, off, size, count int) []methodsig {
-	var buf bytes.Buffer
-	var methods []methodsig
-	for i := 0; i < count; i++ {
-		buf.WriteString(decodetypeName2(ldr, symIdx, symRelocs, off))
-		mtypSym := decodeRelocSym2(ldr, symIdx, symRelocs, int32(off+4))
-		// FIXME: add some sort of caching here, since we may see some of the
-		// same symbols over time for param types.
-		d.ReadRelocs(mtypSym)
-		mp := ldr.Data(mtypSym)
-
-		buf.WriteRune('(')
-		inCount := decodetypeFuncInCount(arch, mp)
-		for i := 0; i < inCount; i++ {
-			if i > 0 {
-				buf.WriteString(", ")
-			}
-			a := d.decodetypeFuncInType2(ldr, arch, mtypSym, d.rtmp, i)
-			buf.WriteString(ldr.SymName(a))
-		}
-		buf.WriteString(") (")
-		outCount := decodetypeFuncOutCount(arch, mp)
-		for i := 0; i < outCount; i++ {
-			if i > 0 {
-				buf.WriteString(", ")
-			}
-			a := d.decodetypeFuncOutType2(ldr, arch, mtypSym, d.rtmp, i)
-			buf.WriteString(ldr.SymName(a))
-		}
-		buf.WriteRune(')')
-
-		off += size
-		methods = append(methods, methodsig(buf.String()))
-		buf.Reset()
-	}
-	return methods
-}
-
-func (d *deadcodePass2) decodeIfaceMethods2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, symRelocs []loader.Reloc) []methodsig {
-	p := ldr.Data(symIdx)
-	if decodetypeKind(arch, p)&kindMask != kindInterface {
-		panic(fmt.Sprintf("symbol %q is not an interface", ldr.SymName(symIdx)))
-	}
-	rel := decodeReloc2(ldr, symIdx, symRelocs, int32(commonsize(arch)+arch.PtrSize))
-	if rel.Sym == 0 {
-		return nil
-	}
-	if rel.Sym != symIdx {
-		panic(fmt.Sprintf("imethod slice pointer in %q leads to a different symbol", ldr.SymName(symIdx)))
-	}
-	off := int(rel.Add) // array of reflect.imethod values
-	numMethods := int(decodetypeIfaceMethodCount(arch, p))
-	sizeofIMethod := 4 + 4
-	return d.decodeMethodSig2(ldr, arch, symIdx, symRelocs, off, sizeofIMethod, numMethods)
-}
-
-func (d *deadcodePass2) decodetypeMethods2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, symRelocs []loader.Reloc) []methodsig {
-	p := ldr.Data(symIdx)
-	if !decodetypeHasUncommon(arch, p) {
-		panic(fmt.Sprintf("no methods on %q", ldr.SymName(symIdx)))
-	}
-	off := commonsize(arch) // reflect.rtype
-	switch decodetypeKind(arch, p) & kindMask {
-	case kindStruct: // reflect.structType
-		off += 4 * arch.PtrSize
-	case kindPtr: // reflect.ptrType
-		off += arch.PtrSize
-	case kindFunc: // reflect.funcType
-		off += arch.PtrSize // 4 bytes, pointer aligned
-	case kindSlice: // reflect.sliceType
-		off += arch.PtrSize
-	case kindArray: // reflect.arrayType
-		off += 3 * arch.PtrSize
-	case kindChan: // reflect.chanType
-		off += 2 * arch.PtrSize
-	case kindMap: // reflect.mapType
-		off += 4*arch.PtrSize + 8
-	case kindInterface: // reflect.interfaceType
-		off += 3 * arch.PtrSize
-	default:
-		// just Sizeof(rtype)
-	}
-
-	mcount := int(decodeInuxi(arch, p[off+4:], 2))
-	moff := int(decodeInuxi(arch, p[off+4+2+2:], 4))
-	off += moff                // offset to array of reflect.method values
-	const sizeofMethod = 4 * 4 // sizeof reflect.method in program
-	return d.decodeMethodSig2(ldr, arch, symIdx, symRelocs, off, sizeofMethod, mcount)
-}
-
-func decodeReloc2(ldr *loader.Loader, symIdx loader.Sym, symRelocs []loader.Reloc, off int32) loader.Reloc {
-	for j := 0; j < len(symRelocs); j++ {
-		rel := symRelocs[j]
-		if rel.Off == off {
-			return rel
-		}
-	}
-	return loader.Reloc{}
-}
-
-func decodeRelocSym2(ldr *loader.Loader, symIdx loader.Sym, symRelocs []loader.Reloc, off int32) loader.Sym {
-	return decodeReloc2(ldr, symIdx, symRelocs, off).Sym
-}
-
-// decodetypeName2 decodes the name from a reflect.name.
-func decodetypeName2(ldr *loader.Loader, symIdx loader.Sym, symRelocs []loader.Reloc, off int) string {
-	r := decodeRelocSym2(ldr, symIdx, symRelocs, int32(off))
-	if r == 0 {
-		return ""
-	}
-
-	data := ldr.Data(r)
-	namelen := int(uint16(data[1])<<8 | uint16(data[2]))
-	return string(data[3 : 3+namelen])
-}
-
-func (d *deadcodePass2) decodetypeFuncInType2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, symRelocs []loader.Reloc, i int) loader.Sym {
-	uadd := commonsize(arch) + 4
-	if arch.PtrSize == 8 {
-		uadd += 4
-	}
-	if decodetypeHasUncommon(arch, ldr.Data(symIdx)) {
-		uadd += uncommonSize()
-	}
-	return decodeRelocSym2(ldr, symIdx, symRelocs, int32(uadd+i*arch.PtrSize))
-}
-
-func (d *deadcodePass2) decodetypeFuncOutType2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, symRelocs []loader.Reloc, i int) loader.Sym {
-	return d.decodetypeFuncInType2(ldr, arch, symIdx, symRelocs, i+decodetypeFuncInCount(arch, ldr.Data(symIdx)))
-}
-
-// readRelocs reads the relocations for the specified symbol into the
-// deadcode relocs work array. Use with care, since the work array
-// is a singleton.
-func (d *deadcodePass2) ReadRelocs(symIdx loader.Sym) {
-	relocs := d.ldr.Relocs(symIdx)
-	d.rtmp = relocs.ReadAll(d.rtmp)
-}
diff --git a/src/cmd/oldlink/internal/ld/decodesym.go b/src/cmd/oldlink/internal/ld/decodesym.go
deleted file mode 100644
index 0676e94..0000000
--- a/src/cmd/oldlink/internal/ld/decodesym.go
+++ /dev/null
@@ -1,374 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ld
-
-import (
-	"bytes"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/sym"
-	"debug/elf"
-	"fmt"
-)
-
-// Decoding the type.* symbols.	 This has to be in sync with
-// ../../runtime/type.go, or more specifically, with what
-// cmd/compile/internal/gc/reflect.go stuffs in these.
-
-// tflag is documented in reflect/type.go.
-//
-// tflag values must be kept in sync with copies in:
-//	cmd/compile/internal/gc/reflect.go
-//	cmd/oldlink/internal/ld/decodesym.go
-//	reflect/type.go
-//	runtime/type.go
-const (
-	tflagUncommon  = 1 << 0
-	tflagExtraStar = 1 << 1
-)
-
-func decodeReloc(s *sym.Symbol, off int32) *sym.Reloc {
-	for i := range s.R {
-		if s.R[i].Off == off {
-			return &s.R[i]
-		}
-	}
-	return nil
-}
-
-func decodeRelocSym(s *sym.Symbol, off int32) *sym.Symbol {
-	r := decodeReloc(s, off)
-	if r == nil {
-		return nil
-	}
-	return r.Sym
-}
-
-func decodeInuxi(arch *sys.Arch, p []byte, sz int) uint64 {
-	switch sz {
-	case 2:
-		return uint64(arch.ByteOrder.Uint16(p))
-	case 4:
-		return uint64(arch.ByteOrder.Uint32(p))
-	case 8:
-		return arch.ByteOrder.Uint64(p)
-	default:
-		Exitf("dwarf: decode inuxi %d", sz)
-		panic("unreachable")
-	}
-}
-
-func commonsize(arch *sys.Arch) int      { return 4*arch.PtrSize + 8 + 8 } // runtime._type
-func structfieldSize(arch *sys.Arch) int { return 3 * arch.PtrSize }       // runtime.structfield
-func uncommonSize() int                  { return 4 + 2 + 2 + 4 + 4 }      // runtime.uncommontype
-
-// Type.commonType.kind
-func decodetypeKind(arch *sys.Arch, p []byte) uint8 {
-	return p[2*arch.PtrSize+7] & objabi.KindMask //  0x13 / 0x1f
-}
-
-// Type.commonType.kind
-func decodetypeUsegcprog(arch *sys.Arch, p []byte) uint8 {
-	return p[2*arch.PtrSize+7] & objabi.KindGCProg //  0x13 / 0x1f
-}
-
-// Type.commonType.size
-func decodetypeSize(arch *sys.Arch, p []byte) int64 {
-	return int64(decodeInuxi(arch, p, arch.PtrSize)) // 0x8 / 0x10
-}
-
-// Type.commonType.ptrdata
-func decodetypePtrdata(arch *sys.Arch, p []byte) int64 {
-	return int64(decodeInuxi(arch, p[arch.PtrSize:], arch.PtrSize)) // 0x8 / 0x10
-}
-
-// Type.commonType.tflag
-func decodetypeHasUncommon(arch *sys.Arch, p []byte) bool {
-	return p[2*arch.PtrSize+4]&tflagUncommon != 0
-}
-
-// Find the elf.Section of a given shared library that contains a given address.
-func findShlibSection(ctxt *Link, path string, addr uint64) *elf.Section {
-	for _, shlib := range ctxt.Shlibs {
-		if shlib.Path == path {
-			for _, sect := range shlib.File.Sections {
-				if sect.Addr <= addr && addr <= sect.Addr+sect.Size {
-					return sect
-				}
-			}
-		}
-	}
-	return nil
-}
-
-// Type.commonType.gc
-func decodetypeGcprog(ctxt *Link, s *sym.Symbol) []byte {
-	if s.Type == sym.SDYNIMPORT {
-		addr := decodetypeGcprogShlib(ctxt, s)
-		sect := findShlibSection(ctxt, s.File, addr)
-		if sect != nil {
-			// A gcprog is a 4-byte uint32 indicating length, followed by
-			// the actual program.
-			progsize := make([]byte, 4)
-			sect.ReadAt(progsize, int64(addr-sect.Addr))
-			progbytes := make([]byte, ctxt.Arch.ByteOrder.Uint32(progsize))
-			sect.ReadAt(progbytes, int64(addr-sect.Addr+4))
-			return append(progsize, progbytes...)
-		}
-		Exitf("cannot find gcprog for %s", s.Name)
-		return nil
-	}
-	return decodeRelocSym(s, 2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize)).P
-}
-
-func decodetypeGcprogShlib(ctxt *Link, s *sym.Symbol) uint64 {
-	if ctxt.Arch.Family == sys.ARM64 {
-		for _, shlib := range ctxt.Shlibs {
-			if shlib.Path == s.File {
-				return shlib.gcdataAddresses[s]
-			}
-		}
-		return 0
-	}
-	return decodeInuxi(ctxt.Arch, s.P[2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize):], ctxt.Arch.PtrSize)
-}
-
-func decodetypeGcmask(ctxt *Link, s *sym.Symbol) []byte {
-	if s.Type == sym.SDYNIMPORT {
-		addr := decodetypeGcprogShlib(ctxt, s)
-		ptrdata := decodetypePtrdata(ctxt.Arch, s.P)
-		sect := findShlibSection(ctxt, s.File, addr)
-		if sect != nil {
-			r := make([]byte, ptrdata/int64(ctxt.Arch.PtrSize))
-			sect.ReadAt(r, int64(addr-sect.Addr))
-			return r
-		}
-		Exitf("cannot find gcmask for %s", s.Name)
-		return nil
-	}
-	mask := decodeRelocSym(s, 2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize))
-	return mask.P
-}
-
-// Type.ArrayType.elem and Type.SliceType.Elem
-func decodetypeArrayElem(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
-	return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
-}
-
-func decodetypeArrayLen(arch *sys.Arch, s *sym.Symbol) int64 {
-	return int64(decodeInuxi(arch, s.P[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
-}
-
-// Type.PtrType.elem
-func decodetypePtrElem(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
-	return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
-}
-
-// Type.MapType.key, elem
-func decodetypeMapKey(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
-	return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
-}
-
-func decodetypeMapValue(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
-	return decodeRelocSym(s, int32(commonsize(arch))+int32(arch.PtrSize)) // 0x20 / 0x38
-}
-
-// Type.ChanType.elem
-func decodetypeChanElem(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
-	return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
-}
-
-// Type.FuncType.dotdotdot
-func decodetypeFuncDotdotdot(arch *sys.Arch, p []byte) bool {
-	return uint16(decodeInuxi(arch, p[commonsize(arch)+2:], 2))&(1<<15) != 0
-}
-
-// Type.FuncType.inCount
-func decodetypeFuncInCount(arch *sys.Arch, p []byte) int {
-	return int(decodeInuxi(arch, p[commonsize(arch):], 2))
-}
-
-func decodetypeFuncOutCount(arch *sys.Arch, p []byte) int {
-	return int(uint16(decodeInuxi(arch, p[commonsize(arch)+2:], 2)) & (1<<15 - 1))
-}
-
-func decodetypeFuncInType(arch *sys.Arch, s *sym.Symbol, i int) *sym.Symbol {
-	uadd := commonsize(arch) + 4
-	if arch.PtrSize == 8 {
-		uadd += 4
-	}
-	if decodetypeHasUncommon(arch, s.P) {
-		uadd += uncommonSize()
-	}
-	return decodeRelocSym(s, int32(uadd+i*arch.PtrSize))
-}
-
-func decodetypeFuncOutType(arch *sys.Arch, s *sym.Symbol, i int) *sym.Symbol {
-	return decodetypeFuncInType(arch, s, i+decodetypeFuncInCount(arch, s.P))
-}
-
-// Type.StructType.fields.Slice::length
-func decodetypeStructFieldCount(arch *sys.Arch, s *sym.Symbol) int {
-	return int(decodeInuxi(arch, s.P[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
-}
-
-func decodetypeStructFieldArrayOff(arch *sys.Arch, s *sym.Symbol, i int) int {
-	off := commonsize(arch) + 4*arch.PtrSize
-	if decodetypeHasUncommon(arch, s.P) {
-		off += uncommonSize()
-	}
-	off += i * structfieldSize(arch)
-	return off
-}
-
-// decodetypeStr returns the contents of an rtype's str field (a nameOff).
-func decodetypeStr(arch *sys.Arch, s *sym.Symbol) string {
-	str := decodetypeName(s, 4*arch.PtrSize+8)
-	if s.P[2*arch.PtrSize+4]&tflagExtraStar != 0 {
-		return str[1:]
-	}
-	return str
-}
-
-// decodetypeName decodes the name from a reflect.name.
-func decodetypeName(s *sym.Symbol, off int) string {
-	r := decodeReloc(s, int32(off))
-	if r == nil {
-		return ""
-	}
-
-	data := r.Sym.P
-	namelen := int(uint16(data[1])<<8 | uint16(data[2]))
-	return string(data[3 : 3+namelen])
-}
-
-func decodetypeStructFieldName(arch *sys.Arch, s *sym.Symbol, i int) string {
-	off := decodetypeStructFieldArrayOff(arch, s, i)
-	return decodetypeName(s, off)
-}
-
-func decodetypeStructFieldType(arch *sys.Arch, s *sym.Symbol, i int) *sym.Symbol {
-	off := decodetypeStructFieldArrayOff(arch, s, i)
-	return decodeRelocSym(s, int32(off+arch.PtrSize))
-}
-
-func decodetypeStructFieldOffs(arch *sys.Arch, s *sym.Symbol, i int) int64 {
-	return decodetypeStructFieldOffsAnon(arch, s, i) >> 1
-}
-
-func decodetypeStructFieldOffsAnon(arch *sys.Arch, s *sym.Symbol, i int) int64 {
-	off := decodetypeStructFieldArrayOff(arch, s, i)
-	return int64(decodeInuxi(arch, s.P[off+2*arch.PtrSize:], arch.PtrSize))
-}
-
-// InterfaceType.methods.length
-func decodetypeIfaceMethodCount(arch *sys.Arch, p []byte) int64 {
-	return int64(decodeInuxi(arch, p[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
-}
-
-// methodsig is a fully qualified typed method signature, like
-// "Visit(type.go/ast.Node) (type.go/ast.Visitor)".
-type methodsig string
-
-// Matches runtime/typekind.go and reflect.Kind.
-const (
-	kindArray     = 17
-	kindChan      = 18
-	kindFunc      = 19
-	kindInterface = 20
-	kindMap       = 21
-	kindPtr       = 22
-	kindSlice     = 23
-	kindStruct    = 25
-	kindMask      = (1 << 5) - 1
-)
-
-// decodeMethodSig decodes an array of method signature information.
-// Each element of the array is size bytes. The first 4 bytes is a
-// nameOff for the method name, and the next 4 bytes is a typeOff for
-// the function type.
-//
-// Conveniently this is the layout of both runtime.method and runtime.imethod.
-func decodeMethodSig(arch *sys.Arch, s *sym.Symbol, off, size, count int) []methodsig {
-	var buf bytes.Buffer
-	var methods []methodsig
-	for i := 0; i < count; i++ {
-		buf.WriteString(decodetypeName(s, off))
-		mtypSym := decodeRelocSym(s, int32(off+4))
-
-		buf.WriteRune('(')
-		inCount := decodetypeFuncInCount(arch, mtypSym.P)
-		for i := 0; i < inCount; i++ {
-			if i > 0 {
-				buf.WriteString(", ")
-			}
-			buf.WriteString(decodetypeFuncInType(arch, mtypSym, i).Name)
-		}
-		buf.WriteString(") (")
-		outCount := decodetypeFuncOutCount(arch, mtypSym.P)
-		for i := 0; i < outCount; i++ {
-			if i > 0 {
-				buf.WriteString(", ")
-			}
-			buf.WriteString(decodetypeFuncOutType(arch, mtypSym, i).Name)
-		}
-		buf.WriteRune(')')
-
-		off += size
-		methods = append(methods, methodsig(buf.String()))
-		buf.Reset()
-	}
-	return methods
-}
-
-func decodeIfaceMethods(arch *sys.Arch, s *sym.Symbol) []methodsig {
-	if decodetypeKind(arch, s.P)&kindMask != kindInterface {
-		panic(fmt.Sprintf("symbol %q is not an interface", s.Name))
-	}
-	r := decodeReloc(s, int32(commonsize(arch)+arch.PtrSize))
-	if r == nil {
-		return nil
-	}
-	if r.Sym != s {
-		panic(fmt.Sprintf("imethod slice pointer in %q leads to a different symbol", s.Name))
-	}
-	off := int(r.Add) // array of reflect.imethod values
-	numMethods := int(decodetypeIfaceMethodCount(arch, s.P))
-	sizeofIMethod := 4 + 4
-	return decodeMethodSig(arch, s, off, sizeofIMethod, numMethods)
-}
-
-func decodetypeMethods(arch *sys.Arch, s *sym.Symbol) []methodsig {
-	if !decodetypeHasUncommon(arch, s.P) {
-		panic(fmt.Sprintf("no methods on %q", s.Name))
-	}
-	off := commonsize(arch) // reflect.rtype
-	switch decodetypeKind(arch, s.P) & kindMask {
-	case kindStruct: // reflect.structType
-		off += 4 * arch.PtrSize
-	case kindPtr: // reflect.ptrType
-		off += arch.PtrSize
-	case kindFunc: // reflect.funcType
-		off += arch.PtrSize // 4 bytes, pointer aligned
-	case kindSlice: // reflect.sliceType
-		off += arch.PtrSize
-	case kindArray: // reflect.arrayType
-		off += 3 * arch.PtrSize
-	case kindChan: // reflect.chanType
-		off += 2 * arch.PtrSize
-	case kindMap: // reflect.mapType
-		off += 4*arch.PtrSize + 8
-	case kindInterface: // reflect.interfaceType
-		off += 3 * arch.PtrSize
-	default:
-		// just Sizeof(rtype)
-	}
-
-	mcount := int(decodeInuxi(arch, s.P[off+4:], 2))
-	moff := int(decodeInuxi(arch, s.P[off+4+2+2:], 4))
-	off += moff                // offset to array of reflect.method values
-	const sizeofMethod = 4 * 4 // sizeof reflect.method in program
-	return decodeMethodSig(arch, s, off, sizeofMethod, mcount)
-}
diff --git a/src/cmd/oldlink/internal/ld/dwarf.go b/src/cmd/oldlink/internal/ld/dwarf.go
deleted file mode 100644
index 3d5220c..0000000
--- a/src/cmd/oldlink/internal/ld/dwarf.go
+++ /dev/null
@@ -1,2044 +0,0 @@
-// 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.
-
-// TODO/NICETOHAVE:
-//   - eliminate DW_CLS_ if not used
-//   - package info in compilation units
-//   - assign types to their packages
-//   - gdb uses c syntax, meaning clumsy quoting is needed for go identifiers. eg
-//     ptype struct '[]uint8' and qualifiers need to be quoted away
-//   - file:line info for variables
-//   - make strings a typedef so prettyprinters can see the underlying string type
-
-package ld
-
-import (
-	"cmd/internal/dwarf"
-	"cmd/internal/obj"
-	"cmd/internal/objabi"
-	"cmd/internal/src"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/sym"
-	"fmt"
-	"log"
-	"sort"
-	"strings"
-)
-
-type dwctxt struct {
-	linkctxt *Link
-}
-
-func (c dwctxt) PtrSize() int {
-	return c.linkctxt.Arch.PtrSize
-}
-func (c dwctxt) AddInt(s dwarf.Sym, size int, i int64) {
-	ls := s.(*sym.Symbol)
-	ls.AddUintXX(c.linkctxt.Arch, uint64(i), size)
-}
-func (c dwctxt) AddBytes(s dwarf.Sym, b []byte) {
-	ls := s.(*sym.Symbol)
-	ls.AddBytes(b)
-}
-func (c dwctxt) AddString(s dwarf.Sym, v string) {
-	Addstring(s.(*sym.Symbol), v)
-}
-
-func (c dwctxt) AddAddress(s dwarf.Sym, data interface{}, value int64) {
-	if value != 0 {
-		value -= (data.(*sym.Symbol)).Value
-	}
-	s.(*sym.Symbol).AddAddrPlus(c.linkctxt.Arch, data.(*sym.Symbol), value)
-}
-
-func (c dwctxt) AddCURelativeAddress(s dwarf.Sym, data interface{}, value int64) {
-	if value != 0 {
-		value -= (data.(*sym.Symbol)).Value
-	}
-	s.(*sym.Symbol).AddCURelativeAddrPlus(c.linkctxt.Arch, data.(*sym.Symbol), value)
-}
-
-func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) {
-	ls := s.(*sym.Symbol)
-	switch size {
-	default:
-		Errorf(ls, "invalid size %d in adddwarfref\n", size)
-		fallthrough
-	case c.linkctxt.Arch.PtrSize:
-		ls.AddAddr(c.linkctxt.Arch, t.(*sym.Symbol))
-	case 4:
-		ls.AddAddrPlus4(t.(*sym.Symbol), 0)
-	}
-	r := &ls.R[len(ls.R)-1]
-	r.Type = objabi.R_ADDROFF
-	r.Add = ofs
-}
-
-func (c dwctxt) AddDWARFAddrSectionOffset(s dwarf.Sym, t interface{}, ofs int64) {
-	size := 4
-	if isDwarf64(c.linkctxt) {
-		size = 8
-	}
-
-	c.AddSectionOffset(s, size, t, ofs)
-	ls := s.(*sym.Symbol)
-	ls.R[len(ls.R)-1].Type = objabi.R_DWARFSECREF
-}
-
-func (c dwctxt) Logf(format string, args ...interface{}) {
-	c.linkctxt.Logf(format, args...)
-}
-
-// At the moment these interfaces are only used in the compiler.
-
-func (c dwctxt) AddFileRef(s dwarf.Sym, f interface{}) {
-	panic("should be used only in the compiler")
-}
-
-func (c dwctxt) CurrentOffset(s dwarf.Sym) int64 {
-	panic("should be used only in the compiler")
-}
-
-func (c dwctxt) RecordDclReference(s dwarf.Sym, t dwarf.Sym, dclIdx int, inlIndex int) {
-	panic("should be used only in the compiler")
-}
-
-func (c dwctxt) RecordChildDieOffsets(s dwarf.Sym, vars []*dwarf.Var, offsets []int32) {
-	panic("should be used only in the compiler")
-}
-
-func isDwarf64(ctxt *Link) bool {
-	return ctxt.HeadType == objabi.Haix
-}
-
-var gdbscript string
-
-var dwarfp []*sym.Symbol
-
-func writeabbrev(ctxt *Link) *sym.Symbol {
-	s := ctxt.Syms.Lookup(".debug_abbrev", 0)
-	s.Type = sym.SDWARFSECT
-	s.AddBytes(dwarf.GetAbbrev())
-	return s
-}
-
-var dwtypes dwarf.DWDie
-
-func newattr(die *dwarf.DWDie, attr uint16, cls int, value int64, data interface{}) *dwarf.DWAttr {
-	a := new(dwarf.DWAttr)
-	a.Link = die.Attr
-	die.Attr = a
-	a.Atr = attr
-	a.Cls = uint8(cls)
-	a.Value = value
-	a.Data = data
-	return a
-}
-
-// Each DIE (except the root ones) has at least 1 attribute: its
-// name. getattr moves the desired one to the front so
-// frequently searched ones are found faster.
-func getattr(die *dwarf.DWDie, attr uint16) *dwarf.DWAttr {
-	if die.Attr.Atr == attr {
-		return die.Attr
-	}
-
-	a := die.Attr
-	b := a.Link
-	for b != nil {
-		if b.Atr == attr {
-			a.Link = b.Link
-			b.Link = die.Attr
-			die.Attr = b
-			return b
-		}
-
-		a = b
-		b = b.Link
-	}
-
-	return nil
-}
-
-// Every DIE manufactured by the linker has at least an AT_name
-// attribute (but it will only be written out if it is listed in the abbrev).
-// The compiler does create nameless DWARF DIEs (ex: concrete subprogram
-// instance).
-func newdie(ctxt *Link, parent *dwarf.DWDie, abbrev int, name string, version int) *dwarf.DWDie {
-	die := new(dwarf.DWDie)
-	die.Abbrev = abbrev
-	die.Link = parent.Child
-	parent.Child = die
-
-	newattr(die, dwarf.DW_AT_name, dwarf.DW_CLS_STRING, int64(len(name)), name)
-
-	if name != "" && (abbrev <= dwarf.DW_ABRV_VARIABLE || abbrev >= dwarf.DW_ABRV_NULLTYPE) {
-		if abbrev != dwarf.DW_ABRV_VARIABLE || version == 0 {
-			if abbrev == dwarf.DW_ABRV_COMPUNIT {
-				// Avoid collisions with "real" symbol names.
-				name = fmt.Sprintf(".pkg.%s.%d", name, len(ctxt.compUnits))
-			}
-			s := ctxt.Syms.Lookup(dwarf.InfoPrefix+name, version)
-			s.Attr |= sym.AttrNotInSymbolTable
-			s.Type = sym.SDWARFINFO
-			die.Sym = s
-		}
-	}
-
-	return die
-}
-
-func walktypedef(die *dwarf.DWDie) *dwarf.DWDie {
-	if die == nil {
-		return nil
-	}
-	// Resolve typedef if present.
-	if die.Abbrev == dwarf.DW_ABRV_TYPEDECL {
-		for attr := die.Attr; attr != nil; attr = attr.Link {
-			if attr.Atr == dwarf.DW_AT_type && attr.Cls == dwarf.DW_CLS_REFERENCE && attr.Data != nil {
-				return attr.Data.(*dwarf.DWDie)
-			}
-		}
-	}
-
-	return die
-}
-
-func walksymtypedef(ctxt *Link, s *sym.Symbol) *sym.Symbol {
-	if t := ctxt.Syms.ROLookup(s.Name+"..def", int(s.Version)); t != nil {
-		return t
-	}
-	return s
-}
-
-// Find child by AT_name using hashtable if available or linear scan
-// if not.
-func findchild(die *dwarf.DWDie, name string) *dwarf.DWDie {
-	var prev *dwarf.DWDie
-	for ; die != prev; prev, die = die, walktypedef(die) {
-		for a := die.Child; a != nil; a = a.Link {
-			if name == getattr(a, dwarf.DW_AT_name).Data {
-				return a
-			}
-		}
-		continue
-	}
-	return nil
-}
-
-// Used to avoid string allocation when looking up dwarf symbols
-var prefixBuf = []byte(dwarf.InfoPrefix)
-
-func find(ctxt *Link, name string) *sym.Symbol {
-	n := append(prefixBuf, name...)
-	// The string allocation below is optimized away because it is only used in a map lookup.
-	s := ctxt.Syms.ROLookup(string(n), 0)
-	prefixBuf = n[:len(dwarf.InfoPrefix)]
-	if s != nil && s.Type == sym.SDWARFINFO {
-		return s
-	}
-	return nil
-}
-
-func mustFind(ctxt *Link, name string) *sym.Symbol {
-	r := find(ctxt, name)
-	if r == nil {
-		Exitf("dwarf find: cannot find %s", name)
-	}
-	return r
-}
-
-func adddwarfref(ctxt *Link, s *sym.Symbol, t *sym.Symbol, size int) int64 {
-	var result int64
-	switch size {
-	default:
-		Errorf(s, "invalid size %d in adddwarfref\n", size)
-		fallthrough
-	case ctxt.Arch.PtrSize:
-		result = s.AddAddr(ctxt.Arch, t)
-	case 4:
-		result = s.AddAddrPlus4(t, 0)
-	}
-	r := &s.R[len(s.R)-1]
-	r.Type = objabi.R_DWARFSECREF
-	return result
-}
-
-func newrefattr(die *dwarf.DWDie, attr uint16, ref *sym.Symbol) *dwarf.DWAttr {
-	if ref == nil {
-		return nil
-	}
-	return newattr(die, attr, dwarf.DW_CLS_REFERENCE, 0, ref)
-}
-
-func dtolsym(s dwarf.Sym) *sym.Symbol {
-	if s == nil {
-		return nil
-	}
-	return s.(*sym.Symbol)
-}
-
-func putdie(linkctxt *Link, ctxt dwarf.Context, syms []*sym.Symbol, die *dwarf.DWDie) []*sym.Symbol {
-	s := dtolsym(die.Sym)
-	if s == nil {
-		s = syms[len(syms)-1]
-	} else {
-		if s.Attr.OnList() {
-			log.Fatalf("symbol %s listed multiple times", s.Name)
-		}
-		s.Attr |= sym.AttrOnList
-		syms = append(syms, s)
-	}
-	dwarf.Uleb128put(ctxt, s, int64(die.Abbrev))
-	dwarf.PutAttrs(ctxt, s, die.Abbrev, die.Attr)
-	if dwarf.HasChildren(die) {
-		for die := die.Child; die != nil; die = die.Link {
-			syms = putdie(linkctxt, ctxt, syms, die)
-		}
-		syms[len(syms)-1].AddUint8(0)
-	}
-	return syms
-}
-
-func reverselist(list **dwarf.DWDie) {
-	curr := *list
-	var prev *dwarf.DWDie
-	for curr != nil {
-		next := curr.Link
-		curr.Link = prev
-		prev = curr
-		curr = next
-	}
-
-	*list = prev
-}
-
-func reversetree(list **dwarf.DWDie) {
-	reverselist(list)
-	for die := *list; die != nil; die = die.Link {
-		if dwarf.HasChildren(die) {
-			reversetree(&die.Child)
-		}
-	}
-}
-
-func newmemberoffsetattr(die *dwarf.DWDie, offs int32) {
-	newattr(die, dwarf.DW_AT_data_member_location, dwarf.DW_CLS_CONSTANT, int64(offs), nil)
-}
-
-// GDB doesn't like FORM_addr for AT_location, so emit a
-// location expression that evals to a const.
-func newabslocexprattr(die *dwarf.DWDie, addr int64, sym *sym.Symbol) {
-	newattr(die, dwarf.DW_AT_location, dwarf.DW_CLS_ADDRESS, addr, sym)
-	// below
-}
-
-// Lookup predefined types
-func lookupOrDiag(ctxt *Link, n string) *sym.Symbol {
-	s := ctxt.Syms.ROLookup(n, 0)
-	if s == nil || s.Size == 0 {
-		Exitf("dwarf: missing type: %s", n)
-	}
-
-	return s
-}
-
-// dwarfFuncSym looks up a DWARF metadata symbol for function symbol s.
-// If the symbol does not exist, it creates it if create is true,
-// or returns nil otherwise.
-func dwarfFuncSym(ctxt *Link, s *sym.Symbol, meta string, create bool) *sym.Symbol {
-	// All function ABIs use symbol version 0 for the DWARF data.
-	//
-	// TODO(austin): It may be useful to have DWARF info for ABI
-	// wrappers, in which case we may want these versions to
-	// align. Better yet, replace these name lookups with a
-	// general way to attach metadata to a symbol.
-	ver := 0
-	if s.IsFileLocal() {
-		ver = int(s.Version)
-	}
-	if create {
-		return ctxt.Syms.Lookup(meta+s.Name, ver)
-	}
-	return ctxt.Syms.ROLookup(meta+s.Name, ver)
-}
-
-func dotypedef(ctxt *Link, parent *dwarf.DWDie, name string, def *dwarf.DWDie) *dwarf.DWDie {
-	// Only emit typedefs for real names.
-	if strings.HasPrefix(name, "map[") {
-		return nil
-	}
-	if strings.HasPrefix(name, "struct {") {
-		return nil
-	}
-	if strings.HasPrefix(name, "chan ") {
-		return nil
-	}
-	if name[0] == '[' || name[0] == '*' {
-		return nil
-	}
-	if def == nil {
-		Errorf(nil, "dwarf: bad def in dotypedef")
-	}
-
-	s := ctxt.Syms.Lookup(dtolsym(def.Sym).Name+"..def", 0)
-	s.Attr |= sym.AttrNotInSymbolTable
-	s.Type = sym.SDWARFINFO
-	def.Sym = s
-
-	// The typedef entry must be created after the def,
-	// so that future lookups will find the typedef instead
-	// of the real definition. This hooks the typedef into any
-	// circular definition loops, so that gdb can understand them.
-	die := newdie(ctxt, parent, dwarf.DW_ABRV_TYPEDECL, name, 0)
-
-	newrefattr(die, dwarf.DW_AT_type, s)
-
-	return die
-}
-
-// Define gotype, for composite ones recurse into constituents.
-func defgotype(ctxt *Link, gotype *sym.Symbol) *sym.Symbol {
-	if gotype == nil {
-		return mustFind(ctxt, "<unspecified>")
-	}
-
-	if !strings.HasPrefix(gotype.Name, "type.") {
-		Errorf(gotype, "dwarf: type name doesn't start with \"type.\"")
-		return mustFind(ctxt, "<unspecified>")
-	}
-
-	name := gotype.Name[5:] // could also decode from Type.string
-
-	sdie := find(ctxt, name)
-
-	if sdie != nil {
-		return sdie
-	}
-
-	return newtype(ctxt, gotype).Sym.(*sym.Symbol)
-}
-
-func newtype(ctxt *Link, gotype *sym.Symbol) *dwarf.DWDie {
-	name := gotype.Name[5:] // could also decode from Type.string
-	kind := decodetypeKind(ctxt.Arch, gotype.P)
-	bytesize := decodetypeSize(ctxt.Arch, gotype.P)
-
-	var die, typedefdie *dwarf.DWDie
-	switch kind {
-	case objabi.KindBool:
-		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
-		newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_boolean, 0)
-		newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
-
-	case objabi.KindInt,
-		objabi.KindInt8,
-		objabi.KindInt16,
-		objabi.KindInt32,
-		objabi.KindInt64:
-		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
-		newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_signed, 0)
-		newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
-
-	case objabi.KindUint,
-		objabi.KindUint8,
-		objabi.KindUint16,
-		objabi.KindUint32,
-		objabi.KindUint64,
-		objabi.KindUintptr:
-		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
-		newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_unsigned, 0)
-		newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
-
-	case objabi.KindFloat32,
-		objabi.KindFloat64:
-		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
-		newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_float, 0)
-		newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
-
-	case objabi.KindComplex64,
-		objabi.KindComplex128:
-		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
-		newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_complex_float, 0)
-		newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
-
-	case objabi.KindArray:
-		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_ARRAYTYPE, name, 0)
-		typedefdie = dotypedef(ctxt, &dwtypes, name, die)
-		newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
-		s := decodetypeArrayElem(ctxt.Arch, gotype)
-		newrefattr(die, dwarf.DW_AT_type, defgotype(ctxt, s))
-		fld := newdie(ctxt, die, dwarf.DW_ABRV_ARRAYRANGE, "range", 0)
-
-		// use actual length not upper bound; correct for 0-length arrays.
-		newattr(fld, dwarf.DW_AT_count, dwarf.DW_CLS_CONSTANT, decodetypeArrayLen(ctxt.Arch, gotype), 0)
-
-		newrefattr(fld, dwarf.DW_AT_type, mustFind(ctxt, "uintptr"))
-
-	case objabi.KindChan:
-		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_CHANTYPE, name, 0)
-		s := decodetypeChanElem(ctxt.Arch, gotype)
-		newrefattr(die, dwarf.DW_AT_go_elem, defgotype(ctxt, s))
-		// Save elem type for synthesizechantypes. We could synthesize here
-		// but that would change the order of DIEs we output.
-		newrefattr(die, dwarf.DW_AT_type, s)
-
-	case objabi.KindFunc:
-		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_FUNCTYPE, name, 0)
-		newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
-		typedefdie = dotypedef(ctxt, &dwtypes, name, die)
-		nfields := decodetypeFuncInCount(ctxt.Arch, gotype.P)
-		for i := 0; i < nfields; i++ {
-			s := decodetypeFuncInType(ctxt.Arch, gotype, i)
-			fld := newdie(ctxt, die, dwarf.DW_ABRV_FUNCTYPEPARAM, s.Name[5:], 0)
-			newrefattr(fld, dwarf.DW_AT_type, defgotype(ctxt, s))
-		}
-
-		if decodetypeFuncDotdotdot(ctxt.Arch, gotype.P) {
-			newdie(ctxt, die, dwarf.DW_ABRV_DOTDOTDOT, "...", 0)
-		}
-		nfields = decodetypeFuncOutCount(ctxt.Arch, gotype.P)
-		for i := 0; i < nfields; i++ {
-			s := decodetypeFuncOutType(ctxt.Arch, gotype, i)
-			fld := newdie(ctxt, die, dwarf.DW_ABRV_FUNCTYPEPARAM, s.Name[5:], 0)
-			newrefattr(fld, dwarf.DW_AT_type, defptrto(ctxt, defgotype(ctxt, s)))
-		}
-
-	case objabi.KindInterface:
-		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_IFACETYPE, name, 0)
-		typedefdie = dotypedef(ctxt, &dwtypes, name, die)
-		nfields := int(decodetypeIfaceMethodCount(ctxt.Arch, gotype.P))
-		var s *sym.Symbol
-		if nfields == 0 {
-			s = lookupOrDiag(ctxt, "type.runtime.eface")
-		} else {
-			s = lookupOrDiag(ctxt, "type.runtime.iface")
-		}
-		newrefattr(die, dwarf.DW_AT_type, defgotype(ctxt, s))
-
-	case objabi.KindMap:
-		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_MAPTYPE, name, 0)
-		s := decodetypeMapKey(ctxt.Arch, gotype)
-		newrefattr(die, dwarf.DW_AT_go_key, defgotype(ctxt, s))
-		s = decodetypeMapValue(ctxt.Arch, gotype)
-		newrefattr(die, dwarf.DW_AT_go_elem, defgotype(ctxt, s))
-		// Save gotype for use in synthesizemaptypes. We could synthesize here,
-		// but that would change the order of the DIEs.
-		newrefattr(die, dwarf.DW_AT_type, gotype)
-
-	case objabi.KindPtr:
-		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_PTRTYPE, name, 0)
-		typedefdie = dotypedef(ctxt, &dwtypes, name, die)
-		s := decodetypePtrElem(ctxt.Arch, gotype)
-		newrefattr(die, dwarf.DW_AT_type, defgotype(ctxt, s))
-
-	case objabi.KindSlice:
-		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_SLICETYPE, name, 0)
-		typedefdie = dotypedef(ctxt, &dwtypes, name, die)
-		newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
-		s := decodetypeArrayElem(ctxt.Arch, gotype)
-		elem := defgotype(ctxt, s)
-		newrefattr(die, dwarf.DW_AT_go_elem, elem)
-
-	case objabi.KindString:
-		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_STRINGTYPE, name, 0)
-		newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
-
-	case objabi.KindStruct:
-		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_STRUCTTYPE, name, 0)
-		typedefdie = dotypedef(ctxt, &dwtypes, name, die)
-		newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
-		nfields := decodetypeStructFieldCount(ctxt.Arch, gotype)
-		for i := 0; i < nfields; i++ {
-			f := decodetypeStructFieldName(ctxt.Arch, gotype, i)
-			s := decodetypeStructFieldType(ctxt.Arch, gotype, i)
-			if f == "" {
-				f = s.Name[5:] // skip "type."
-			}
-			fld := newdie(ctxt, die, dwarf.DW_ABRV_STRUCTFIELD, f, 0)
-			newrefattr(fld, dwarf.DW_AT_type, defgotype(ctxt, s))
-			offsetAnon := decodetypeStructFieldOffsAnon(ctxt.Arch, gotype, i)
-			newmemberoffsetattr(fld, int32(offsetAnon>>1))
-			if offsetAnon&1 != 0 { // is embedded field
-				newattr(fld, dwarf.DW_AT_go_embedded_field, dwarf.DW_CLS_FLAG, 1, 0)
-			}
-		}
-
-	case objabi.KindUnsafePointer:
-		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BARE_PTRTYPE, name, 0)
-
-	default:
-		Errorf(gotype, "dwarf: definition of unknown kind %d", kind)
-		die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_TYPEDECL, name, 0)
-		newrefattr(die, dwarf.DW_AT_type, mustFind(ctxt, "<unspecified>"))
-	}
-
-	newattr(die, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, int64(kind), 0)
-	if gotype.Attr.Reachable() {
-		newattr(die, dwarf.DW_AT_go_runtime_type, dwarf.DW_CLS_GO_TYPEREF, 0, gotype)
-	}
-
-	if _, ok := prototypedies[gotype.Name]; ok {
-		prototypedies[gotype.Name] = die
-	}
-
-	if typedefdie != nil {
-		return typedefdie
-	}
-	return die
-}
-
-func nameFromDIESym(dwtype *sym.Symbol) string {
-	return strings.TrimSuffix(dwtype.Name[len(dwarf.InfoPrefix):], "..def")
-}
-
-// Find or construct *T given T.
-func defptrto(ctxt *Link, dwtype *sym.Symbol) *sym.Symbol {
-	ptrname := "*" + nameFromDIESym(dwtype)
-	if die := find(ctxt, ptrname); die != nil {
-		return die
-	}
-
-	pdie := newdie(ctxt, &dwtypes, dwarf.DW_ABRV_PTRTYPE, ptrname, 0)
-	newrefattr(pdie, dwarf.DW_AT_type, dwtype)
-
-	// The DWARF info synthesizes pointer types that don't exist at the
-	// language level, like *hash<...> and *bucket<...>, and the data
-	// pointers of slices. Link to the ones we can find.
-	gotype := ctxt.Syms.ROLookup("type."+ptrname, 0)
-	if gotype != nil && gotype.Attr.Reachable() {
-		newattr(pdie, dwarf.DW_AT_go_runtime_type, dwarf.DW_CLS_GO_TYPEREF, 0, gotype)
-	}
-	return dtolsym(pdie.Sym)
-}
-
-// Copies src's children into dst. Copies attributes by value.
-// DWAttr.data is copied as pointer only. If except is one of
-// the top-level children, it will not be copied.
-func copychildrenexcept(ctxt *Link, dst *dwarf.DWDie, src *dwarf.DWDie, except *dwarf.DWDie) {
-	for src = src.Child; src != nil; src = src.Link {
-		if src == except {
-			continue
-		}
-		c := newdie(ctxt, dst, src.Abbrev, getattr(src, dwarf.DW_AT_name).Data.(string), 0)
-		for a := src.Attr; a != nil; a = a.Link {
-			newattr(c, a.Atr, int(a.Cls), a.Value, a.Data)
-		}
-		copychildrenexcept(ctxt, c, src, nil)
-	}
-
-	reverselist(&dst.Child)
-}
-
-func copychildren(ctxt *Link, dst *dwarf.DWDie, src *dwarf.DWDie) {
-	copychildrenexcept(ctxt, dst, src, nil)
-}
-
-// Search children (assumed to have TAG_member) for the one named
-// field and set its AT_type to dwtype
-func substitutetype(structdie *dwarf.DWDie, field string, dwtype *sym.Symbol) {
-	child := findchild(structdie, field)
-	if child == nil {
-		Exitf("dwarf substitutetype: %s does not have member %s",
-			getattr(structdie, dwarf.DW_AT_name).Data, field)
-		return
-	}
-
-	a := getattr(child, dwarf.DW_AT_type)
-	if a != nil {
-		a.Data = dwtype
-	} else {
-		newrefattr(child, dwarf.DW_AT_type, dwtype)
-	}
-}
-
-func findprotodie(ctxt *Link, name string) *dwarf.DWDie {
-	die, ok := prototypedies[name]
-	if ok && die == nil {
-		defgotype(ctxt, lookupOrDiag(ctxt, name))
-		die = prototypedies[name]
-	}
-	return die
-}
-
-func synthesizestringtypes(ctxt *Link, die *dwarf.DWDie) {
-	prototype := walktypedef(findprotodie(ctxt, "type.runtime.stringStructDWARF"))
-	if prototype == nil {
-		return
-	}
-
-	for ; die != nil; die = die.Link {
-		if die.Abbrev != dwarf.DW_ABRV_STRINGTYPE {
-			continue
-		}
-		copychildren(ctxt, die, prototype)
-	}
-}
-
-func synthesizeslicetypes(ctxt *Link, die *dwarf.DWDie) {
-	prototype := walktypedef(findprotodie(ctxt, "type.runtime.slice"))
-	if prototype == nil {
-		return
-	}
-
-	for ; die != nil; die = die.Link {
-		if die.Abbrev != dwarf.DW_ABRV_SLICETYPE {
-			continue
-		}
-		copychildren(ctxt, die, prototype)
-		elem := getattr(die, dwarf.DW_AT_go_elem).Data.(*sym.Symbol)
-		substitutetype(die, "array", defptrto(ctxt, elem))
-	}
-}
-
-func mkinternaltypename(base string, arg1 string, arg2 string) string {
-	if arg2 == "" {
-		return fmt.Sprintf("%s<%s>", base, arg1)
-	}
-	return fmt.Sprintf("%s<%s,%s>", base, arg1, arg2)
-}
-
-// synthesizemaptypes is way too closely married to runtime/hashmap.c
-const (
-	MaxKeySize = 128
-	MaxValSize = 128
-	BucketSize = 8
-)
-
-func mkinternaltype(ctxt *Link, abbrev int, typename, keyname, valname string, f func(*dwarf.DWDie)) *sym.Symbol {
-	name := mkinternaltypename(typename, keyname, valname)
-	symname := dwarf.InfoPrefix + name
-	s := ctxt.Syms.ROLookup(symname, 0)
-	if s != nil && s.Type == sym.SDWARFINFO {
-		return s
-	}
-	die := newdie(ctxt, &dwtypes, abbrev, name, 0)
-	f(die)
-	return dtolsym(die.Sym)
-}
-
-func synthesizemaptypes(ctxt *Link, die *dwarf.DWDie) {
-	hash := walktypedef(findprotodie(ctxt, "type.runtime.hmap"))
-	bucket := walktypedef(findprotodie(ctxt, "type.runtime.bmap"))
-
-	if hash == nil {
-		return
-	}
-
-	for ; die != nil; die = die.Link {
-		if die.Abbrev != dwarf.DW_ABRV_MAPTYPE {
-			continue
-		}
-		gotype := getattr(die, dwarf.DW_AT_type).Data.(*sym.Symbol)
-		keytype := decodetypeMapKey(ctxt.Arch, gotype)
-		valtype := decodetypeMapValue(ctxt.Arch, gotype)
-		keysize, valsize := decodetypeSize(ctxt.Arch, keytype.P), decodetypeSize(ctxt.Arch, valtype.P)
-		keytype, valtype = walksymtypedef(ctxt, defgotype(ctxt, keytype)), walksymtypedef(ctxt, defgotype(ctxt, valtype))
-
-		// compute size info like hashmap.c does.
-		indirectKey, indirectVal := false, false
-		if keysize > MaxKeySize {
-			keysize = int64(ctxt.Arch.PtrSize)
-			indirectKey = true
-		}
-		if valsize > MaxValSize {
-			valsize = int64(ctxt.Arch.PtrSize)
-			indirectVal = true
-		}
-
-		// Construct type to represent an array of BucketSize keys
-		keyname := nameFromDIESym(keytype)
-		dwhks := mkinternaltype(ctxt, dwarf.DW_ABRV_ARRAYTYPE, "[]key", keyname, "", func(dwhk *dwarf.DWDie) {
-			newattr(dwhk, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, BucketSize*keysize, 0)
-			t := keytype
-			if indirectKey {
-				t = defptrto(ctxt, keytype)
-			}
-			newrefattr(dwhk, dwarf.DW_AT_type, t)
-			fld := newdie(ctxt, dwhk, dwarf.DW_ABRV_ARRAYRANGE, "size", 0)
-			newattr(fld, dwarf.DW_AT_count, dwarf.DW_CLS_CONSTANT, BucketSize, 0)
-			newrefattr(fld, dwarf.DW_AT_type, mustFind(ctxt, "uintptr"))
-		})
-
-		// Construct type to represent an array of BucketSize values
-		valname := nameFromDIESym(valtype)
-		dwhvs := mkinternaltype(ctxt, dwarf.DW_ABRV_ARRAYTYPE, "[]val", valname, "", func(dwhv *dwarf.DWDie) {
-			newattr(dwhv, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, BucketSize*valsize, 0)
-			t := valtype
-			if indirectVal {
-				t = defptrto(ctxt, valtype)
-			}
-			newrefattr(dwhv, dwarf.DW_AT_type, t)
-			fld := newdie(ctxt, dwhv, dwarf.DW_ABRV_ARRAYRANGE, "size", 0)
-			newattr(fld, dwarf.DW_AT_count, dwarf.DW_CLS_CONSTANT, BucketSize, 0)
-			newrefattr(fld, dwarf.DW_AT_type, mustFind(ctxt, "uintptr"))
-		})
-
-		// Construct bucket<K,V>
-		dwhbs := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "bucket", keyname, valname, func(dwhb *dwarf.DWDie) {
-			// Copy over all fields except the field "data" from the generic
-			// bucket. "data" will be replaced with keys/values below.
-			copychildrenexcept(ctxt, dwhb, bucket, findchild(bucket, "data"))
-
-			fld := newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "keys", 0)
-			newrefattr(fld, dwarf.DW_AT_type, dwhks)
-			newmemberoffsetattr(fld, BucketSize)
-			fld = newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "values", 0)
-			newrefattr(fld, dwarf.DW_AT_type, dwhvs)
-			newmemberoffsetattr(fld, BucketSize+BucketSize*int32(keysize))
-			fld = newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "overflow", 0)
-			newrefattr(fld, dwarf.DW_AT_type, defptrto(ctxt, dtolsym(dwhb.Sym)))
-			newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize)))
-			if ctxt.Arch.RegSize > ctxt.Arch.PtrSize {
-				fld = newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "pad", 0)
-				newrefattr(fld, dwarf.DW_AT_type, mustFind(ctxt, "uintptr"))
-				newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(ctxt.Arch.PtrSize))
-			}
-
-			newattr(dwhb, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, BucketSize+BucketSize*keysize+BucketSize*valsize+int64(ctxt.Arch.RegSize), 0)
-		})
-
-		// Construct hash<K,V>
-		dwhs := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "hash", keyname, valname, func(dwh *dwarf.DWDie) {
-			copychildren(ctxt, dwh, hash)
-			substitutetype(dwh, "buckets", defptrto(ctxt, dwhbs))
-			substitutetype(dwh, "oldbuckets", defptrto(ctxt, dwhbs))
-			newattr(dwh, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(hash, dwarf.DW_AT_byte_size).Value, nil)
-		})
-
-		// make map type a pointer to hash<K,V>
-		newrefattr(die, dwarf.DW_AT_type, defptrto(ctxt, dwhs))
-	}
-}
-
-func synthesizechantypes(ctxt *Link, die *dwarf.DWDie) {
-	sudog := walktypedef(findprotodie(ctxt, "type.runtime.sudog"))
-	waitq := walktypedef(findprotodie(ctxt, "type.runtime.waitq"))
-	hchan := walktypedef(findprotodie(ctxt, "type.runtime.hchan"))
-	if sudog == nil || waitq == nil || hchan == nil {
-		return
-	}
-
-	sudogsize := int(getattr(sudog, dwarf.DW_AT_byte_size).Value)
-
-	for ; die != nil; die = die.Link {
-		if die.Abbrev != dwarf.DW_ABRV_CHANTYPE {
-			continue
-		}
-		elemgotype := getattr(die, dwarf.DW_AT_type).Data.(*sym.Symbol)
-		elemname := elemgotype.Name[5:]
-		elemtype := walksymtypedef(ctxt, defgotype(ctxt, elemgotype))
-
-		// sudog<T>
-		dwss := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "sudog", elemname, "", func(dws *dwarf.DWDie) {
-			copychildren(ctxt, dws, sudog)
-			substitutetype(dws, "elem", defptrto(ctxt, elemtype))
-			newattr(dws, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(sudogsize), nil)
-		})
-
-		// waitq<T>
-		dwws := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "waitq", elemname, "", func(dww *dwarf.DWDie) {
-
-			copychildren(ctxt, dww, waitq)
-			substitutetype(dww, "first", defptrto(ctxt, dwss))
-			substitutetype(dww, "last", defptrto(ctxt, dwss))
-			newattr(dww, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(waitq, dwarf.DW_AT_byte_size).Value, nil)
-		})
-
-		// hchan<T>
-		dwhs := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "hchan", elemname, "", func(dwh *dwarf.DWDie) {
-			copychildren(ctxt, dwh, hchan)
-			substitutetype(dwh, "recvq", dwws)
-			substitutetype(dwh, "sendq", dwws)
-			newattr(dwh, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(hchan, dwarf.DW_AT_byte_size).Value, nil)
-		})
-
-		newrefattr(die, dwarf.DW_AT_type, defptrto(ctxt, dwhs))
-	}
-}
-
-func dwarfDefineGlobal(ctxt *Link, s *sym.Symbol, str string, v int64, gotype *sym.Symbol) {
-	// Find a suitable CU DIE to include the global.
-	// One would think it's as simple as just looking at the unit, but that might
-	// not have any reachable code. So, we go to the runtime's CU if our unit
-	// isn't otherwise reachable.
-	var unit *sym.CompilationUnit
-	if s.Unit != nil {
-		unit = s.Unit
-	} else {
-		unit = ctxt.runtimeCU
-	}
-	dv := newdie(ctxt, unit.DWInfo, dwarf.DW_ABRV_VARIABLE, str, int(s.Version))
-	newabslocexprattr(dv, v, s)
-	if !s.IsFileLocal() {
-		newattr(dv, dwarf.DW_AT_external, dwarf.DW_CLS_FLAG, 1, 0)
-	}
-	dt := defgotype(ctxt, gotype)
-	newrefattr(dv, dwarf.DW_AT_type, dt)
-}
-
-// For use with pass.c::genasmsym
-func defdwsymb(ctxt *Link, s *sym.Symbol, str string, t SymbolType, v int64, gotype *sym.Symbol) {
-	if strings.HasPrefix(str, "go.string.") {
-		return
-	}
-	if strings.HasPrefix(str, "runtime.gcbits.") {
-		return
-	}
-
-	switch t {
-	case DataSym, BSSSym:
-		switch s.Type {
-		case sym.SDATA, sym.SNOPTRDATA, sym.STYPE, sym.SBSS, sym.SNOPTRBSS, sym.STLSBSS:
-			// ok
-		case sym.SRODATA:
-			if gotype != nil {
-				defgotype(ctxt, gotype)
-			}
-			return
-		default:
-			return
-		}
-		if ctxt.LinkMode != LinkExternal && isStaticTemp(s.Name) {
-			return
-		}
-		dwarfDefineGlobal(ctxt, s, str, v, gotype)
-
-	case AutoSym, ParamSym, DeletedAutoSym:
-		defgotype(ctxt, gotype)
-	}
-}
-
-// createUnitLength creates the initial length field with value v and update
-// offset of unit_length if needed.
-func createUnitLength(ctxt *Link, s *sym.Symbol, v uint64) {
-	if isDwarf64(ctxt) {
-		s.AddUint32(ctxt.Arch, 0xFFFFFFFF)
-	}
-	addDwarfAddrField(ctxt, s, v)
-}
-
-// addDwarfAddrField adds a DWARF field in DWARF 64bits or 32bits.
-func addDwarfAddrField(ctxt *Link, s *sym.Symbol, v uint64) {
-	if isDwarf64(ctxt) {
-		s.AddUint(ctxt.Arch, v)
-	} else {
-		s.AddUint32(ctxt.Arch, uint32(v))
-	}
-}
-
-// addDwarfAddrRef adds a DWARF pointer in DWARF 64bits or 32bits.
-func addDwarfAddrRef(ctxt *Link, s *sym.Symbol, t *sym.Symbol) {
-	if isDwarf64(ctxt) {
-		adddwarfref(ctxt, s, t, 8)
-	} else {
-		adddwarfref(ctxt, s, t, 4)
-	}
-}
-
-// calcCompUnitRanges calculates the PC ranges of the compilation units.
-func calcCompUnitRanges(ctxt *Link) {
-	var prevUnit *sym.CompilationUnit
-	for _, s := range ctxt.Textp {
-		if s.FuncInfo == nil {
-			continue
-		}
-		// Skip linker-created functions (ex: runtime.addmoduledata), since they
-		// don't have DWARF to begin with.
-		if s.Unit == nil {
-			continue
-		}
-		unit := s.Unit
-		// Update PC ranges.
-		//
-		// We don't simply compare the end of the previous
-		// symbol with the start of the next because there's
-		// often a little padding between them. Instead, we
-		// only create boundaries between symbols from
-		// different units.
-		if prevUnit != unit {
-			unit.PCs = append(unit.PCs, dwarf.Range{Start: s.Value - unit.Textp[0].Value})
-			prevUnit = unit
-		}
-		unit.PCs[len(unit.PCs)-1].End = s.Value - unit.Textp[0].Value + s.Size
-	}
-}
-
-func movetomodule(ctxt *Link, parent *dwarf.DWDie) {
-	die := ctxt.runtimeCU.DWInfo.Child
-	if die == nil {
-		ctxt.runtimeCU.DWInfo.Child = parent.Child
-		return
-	}
-	for die.Link != nil {
-		die = die.Link
-	}
-	die.Link = parent.Child
-}
-
-// If the pcln table contains runtime/proc.go, use that to set gdbscript path.
-func finddebugruntimepath(s *sym.Symbol) {
-	if gdbscript != "" {
-		return
-	}
-
-	for i := range s.FuncInfo.File {
-		f := s.FuncInfo.File[i]
-		// We can't use something that may be dead-code
-		// eliminated from a binary here. proc.go contains
-		// main and the scheduler, so it's not going anywhere.
-		if i := strings.Index(f.Name, "runtime/proc.go"); i >= 0 {
-			gdbscript = f.Name[:i] + "runtime/runtime-gdb.py"
-			break
-		}
-	}
-}
-
-/*
- * Generate a sequence of opcodes that is as short as possible.
- * See section 6.2.5
- */
-const (
-	LINE_BASE   = -4
-	LINE_RANGE  = 10
-	PC_RANGE    = (255 - OPCODE_BASE) / LINE_RANGE
-	OPCODE_BASE = 11
-)
-
-/*
- * Walk prog table, emit line program and build DIE tree.
- */
-
-func getCompilationDir() string {
-	// OSX requires this be set to something, but it's not easy to choose
-	// a value. Linking takes place in a temporary directory, so there's
-	// no point including it here. Paths in the file table are usually
-	// absolute, in which case debuggers will ignore this value. -trimpath
-	// produces relative paths, but we don't know where they start, so
-	// all we can do here is try not to make things worse.
-	return "."
-}
-
-func importInfoSymbol(ctxt *Link, dsym *sym.Symbol) {
-	dsym.Attr |= sym.AttrNotInSymbolTable | sym.AttrReachable
-	dsym.Type = sym.SDWARFINFO
-	for i := range dsym.R {
-		r := &dsym.R[i] // Copying sym.Reloc has measurable impact on performance
-		if r.Type == objabi.R_DWARFSECREF && r.Sym.Size == 0 {
-			n := nameFromDIESym(r.Sym)
-			defgotype(ctxt, ctxt.Syms.Lookup("type."+n, 0))
-		}
-	}
-}
-
-func writelines(ctxt *Link, unit *sym.CompilationUnit, ls *sym.Symbol) {
-
-	var dwarfctxt dwarf.Context = dwctxt{ctxt}
-	is_stmt := uint8(1) // initially = recommended default_is_stmt = 1, tracks is_stmt toggles.
-
-	unitstart := int64(-1)
-	headerstart := int64(-1)
-	headerend := int64(-1)
-
-	newattr(unit.DWInfo, dwarf.DW_AT_stmt_list, dwarf.DW_CLS_PTR, ls.Size, ls)
-
-	// Write .debug_line Line Number Program Header (sec 6.2.4)
-	// Fields marked with (*) must be changed for 64-bit dwarf
-	unitLengthOffset := ls.Size
-	createUnitLength(ctxt, ls, 0) // unit_length (*), filled in at end
-	unitstart = ls.Size
-	ls.AddUint16(ctxt.Arch, 2) // dwarf version (appendix F) -- version 3 is incompatible w/ XCode 9.0's dsymutil, latest supported on OSX 10.12 as of 2018-05
-	headerLengthOffset := ls.Size
-	addDwarfAddrField(ctxt, ls, 0) // header_length (*), filled in at end
-	headerstart = ls.Size
-
-	// cpos == unitstart + 4 + 2 + 4
-	ls.AddUint8(1)                // minimum_instruction_length
-	ls.AddUint8(is_stmt)          // default_is_stmt
-	ls.AddUint8(LINE_BASE & 0xFF) // line_base
-	ls.AddUint8(LINE_RANGE)       // line_range
-	ls.AddUint8(OPCODE_BASE)      // opcode_base
-	ls.AddUint8(0)                // standard_opcode_lengths[1]
-	ls.AddUint8(1)                // standard_opcode_lengths[2]
-	ls.AddUint8(1)                // standard_opcode_lengths[3]
-	ls.AddUint8(1)                // standard_opcode_lengths[4]
-	ls.AddUint8(1)                // standard_opcode_lengths[5]
-	ls.AddUint8(0)                // standard_opcode_lengths[6]
-	ls.AddUint8(0)                // standard_opcode_lengths[7]
-	ls.AddUint8(0)                // standard_opcode_lengths[8]
-	ls.AddUint8(1)                // standard_opcode_lengths[9]
-	ls.AddUint8(0)                // standard_opcode_lengths[10]
-	ls.AddUint8(0)                // include_directories  (empty)
-
-	// Copy over the file table.
-	fileNums := make(map[string]int)
-	for i, name := range unit.DWARFFileTable {
-		if len(name) != 0 {
-			if strings.HasPrefix(name, src.FileSymPrefix) {
-				name = name[len(src.FileSymPrefix):]
-			}
-			name = expandGoroot(name)
-		} else {
-			// Can't have empty filenames, and having a unique filename is quite useful
-			// for debugging.
-			name = fmt.Sprintf("<missing>_%d", i)
-		}
-		fileNums[name] = i + 1
-		dwarfctxt.AddString(ls, name)
-		ls.AddUint8(0)
-		ls.AddUint8(0)
-		ls.AddUint8(0)
-	}
-	// Grab files for inlined functions.
-	// TODO: With difficulty, this could be moved into the compiler.
-	for _, s := range unit.Textp {
-		dsym := dwarfFuncSym(ctxt, s, dwarf.InfoPrefix, true)
-		for ri := 0; ri < len(dsym.R); ri++ {
-			r := &dsym.R[ri]
-			if r.Type != objabi.R_DWARFFILEREF {
-				continue
-			}
-			name := r.Sym.Name
-			if _, ok := fileNums[name]; ok {
-				continue
-			}
-			fileNums[name] = len(fileNums) + 1
-			dwarfctxt.AddString(ls, name)
-			ls.AddUint8(0)
-			ls.AddUint8(0)
-			ls.AddUint8(0)
-		}
-	}
-
-	// 4 zeros: the string termination + 3 fields.
-	ls.AddUint8(0)
-	// terminate file_names.
-	headerend = ls.Size
-
-	// Output the state machine for each function remaining.
-	var lastAddr int64
-	for _, s := range unit.Textp {
-		finddebugruntimepath(s)
-
-		// Set the PC.
-		ls.AddUint8(0)
-		dwarf.Uleb128put(dwarfctxt, ls, 1+int64(ctxt.Arch.PtrSize))
-		ls.AddUint8(dwarf.DW_LNE_set_address)
-		addr := ls.AddAddr(ctxt.Arch, s)
-		// Make sure the units are sorted.
-		if addr < lastAddr {
-			Errorf(s, "address wasn't increasing %x < %x", addr, lastAddr)
-		}
-		lastAddr = addr
-
-		// Output the line table.
-		// TODO: Now that we have all the debug information in separate
-		// symbols, it would make sense to use a rope, and concatenate them all
-		// together rather then the append() below. This would allow us to have
-		// the compiler emit the DW_LNE_set_address and a rope data structure
-		// to concat them all together in the output.
-		lines := dwarfFuncSym(ctxt, s, dwarf.DebugLinesPrefix, false)
-		if lines != nil {
-			ls.P = append(ls.P, lines.P...)
-		}
-	}
-
-	ls.AddUint8(0) // start extended opcode
-	dwarf.Uleb128put(dwarfctxt, ls, 1)
-	ls.AddUint8(dwarf.DW_LNE_end_sequence)
-
-	if ctxt.HeadType == objabi.Haix {
-		saveDwsectCUSize(".debug_line", unit.Lib.Pkg, uint64(ls.Size-unitLengthOffset))
-	}
-	if isDwarf64(ctxt) {
-		ls.SetUint(ctxt.Arch, unitLengthOffset+4, uint64(ls.Size-unitstart)) // +4 because of 0xFFFFFFFF
-		ls.SetUint(ctxt.Arch, headerLengthOffset, uint64(headerend-headerstart))
-	} else {
-		ls.SetUint32(ctxt.Arch, unitLengthOffset, uint32(ls.Size-unitstart))
-		ls.SetUint32(ctxt.Arch, headerLengthOffset, uint32(headerend-headerstart))
-	}
-
-	// Process any R_DWARFFILEREF relocations, since we now know the
-	// line table file indices for this compilation unit. Note that
-	// this loop visits only subprogram DIEs: if the compiler is
-	// changed to generate DW_AT_decl_file attributes for other
-	// DIE flavors (ex: variables) then those DIEs would need to
-	// be included below.
-	missing := make(map[int]interface{})
-	s := unit.Textp[0]
-	for _, f := range unit.FuncDIEs {
-		for ri := range f.R {
-			r := &f.R[ri]
-			if r.Type != objabi.R_DWARFFILEREF {
-				continue
-			}
-			idx, ok := fileNums[r.Sym.Name]
-			if ok {
-				if int(int32(idx)) != idx {
-					Errorf(f, "bad R_DWARFFILEREF relocation: file index overflow")
-				}
-				if r.Siz != 4 {
-					Errorf(f, "bad R_DWARFFILEREF relocation: has size %d, expected 4", r.Siz)
-				}
-				if r.Off < 0 || r.Off+4 > int32(len(f.P)) {
-					Errorf(f, "bad R_DWARFFILEREF relocation offset %d + 4 would write past length %d", r.Off, len(s.P))
-					continue
-				}
-				if r.Add != 0 {
-					Errorf(f, "bad R_DWARFFILEREF relocation: addend not zero")
-				}
-				r.Sym.Attr |= sym.AttrReachable | sym.AttrNotInSymbolTable
-				r.Add = int64(idx) // record the index in r.Add, we'll apply it in the reloc phase.
-			} else {
-				_, found := missing[int(r.Sym.Value)]
-				if !found {
-					Errorf(f, "R_DWARFFILEREF relocation file missing: %v idx %d", r.Sym, r.Sym.Value)
-					missing[int(r.Sym.Value)] = nil
-				}
-			}
-		}
-	}
-}
-
-// writepcranges generates the DW_AT_ranges table for compilation unit cu.
-func writepcranges(ctxt *Link, unit *sym.CompilationUnit, base *sym.Symbol, pcs []dwarf.Range, ranges *sym.Symbol) {
-	var dwarfctxt dwarf.Context = dwctxt{ctxt}
-
-	unitLengthOffset := ranges.Size
-
-	// Create PC ranges for this CU.
-	newattr(unit.DWInfo, dwarf.DW_AT_ranges, dwarf.DW_CLS_PTR, ranges.Size, ranges)
-	newattr(unit.DWInfo, dwarf.DW_AT_low_pc, dwarf.DW_CLS_ADDRESS, base.Value, base)
-	dwarf.PutBasedRanges(dwarfctxt, ranges, pcs)
-
-	if ctxt.HeadType == objabi.Haix {
-		addDwsectCUSize(".debug_ranges", unit.Lib.Pkg, uint64(ranges.Size-unitLengthOffset))
-	}
-
-}
-
-/*
- *  Emit .debug_frame
- */
-const (
-	dataAlignmentFactor = -4
-)
-
-// appendPCDeltaCFA appends per-PC CFA deltas to b and returns the final slice.
-func appendPCDeltaCFA(arch *sys.Arch, b []byte, deltapc, cfa int64) []byte {
-	b = append(b, dwarf.DW_CFA_def_cfa_offset_sf)
-	b = dwarf.AppendSleb128(b, cfa/dataAlignmentFactor)
-
-	switch {
-	case deltapc < 0x40:
-		b = append(b, uint8(dwarf.DW_CFA_advance_loc+deltapc))
-	case deltapc < 0x100:
-		b = append(b, dwarf.DW_CFA_advance_loc1)
-		b = append(b, uint8(deltapc))
-	case deltapc < 0x10000:
-		b = append(b, dwarf.DW_CFA_advance_loc2, 0, 0)
-		arch.ByteOrder.PutUint16(b[len(b)-2:], uint16(deltapc))
-	default:
-		b = append(b, dwarf.DW_CFA_advance_loc4, 0, 0, 0, 0)
-		arch.ByteOrder.PutUint32(b[len(b)-4:], uint32(deltapc))
-	}
-	return b
-}
-
-func writeframes(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
-	var dwarfctxt dwarf.Context = dwctxt{ctxt}
-	fs := ctxt.Syms.Lookup(".debug_frame", 0)
-	fs.Type = sym.SDWARFSECT
-	syms = append(syms, fs)
-
-	// Length field is 4 bytes on Dwarf32 and 12 bytes on Dwarf64
-	lengthFieldSize := int64(4)
-	if isDwarf64(ctxt) {
-		lengthFieldSize += 8
-	}
-
-	// Emit the CIE, Section 6.4.1
-	cieReserve := uint32(16)
-	if haslinkregister(ctxt) {
-		cieReserve = 32
-	}
-	if isDwarf64(ctxt) {
-		cieReserve += 4 // 4 bytes added for cid
-	}
-	createUnitLength(ctxt, fs, uint64(cieReserve))             // initial length, must be multiple of thearch.ptrsize
-	addDwarfAddrField(ctxt, fs, ^uint64(0))                    // cid
-	fs.AddUint8(3)                                             // dwarf version (appendix F)
-	fs.AddUint8(0)                                             // augmentation ""
-	dwarf.Uleb128put(dwarfctxt, fs, 1)                         // code_alignment_factor
-	dwarf.Sleb128put(dwarfctxt, fs, dataAlignmentFactor)       // all CFI offset calculations include multiplication with this factor
-	dwarf.Uleb128put(dwarfctxt, fs, int64(thearch.Dwarfreglr)) // return_address_register
-
-	fs.AddUint8(dwarf.DW_CFA_def_cfa)                          // Set the current frame address..
-	dwarf.Uleb128put(dwarfctxt, fs, int64(thearch.Dwarfregsp)) // ...to use the value in the platform's SP register (defined in l.go)...
-	if haslinkregister(ctxt) {
-		dwarf.Uleb128put(dwarfctxt, fs, int64(0)) // ...plus a 0 offset.
-
-		fs.AddUint8(dwarf.DW_CFA_same_value) // The platform's link register is unchanged during the prologue.
-		dwarf.Uleb128put(dwarfctxt, fs, int64(thearch.Dwarfreglr))
-
-		fs.AddUint8(dwarf.DW_CFA_val_offset)                       // The previous value...
-		dwarf.Uleb128put(dwarfctxt, fs, int64(thearch.Dwarfregsp)) // ...of the platform's SP register...
-		dwarf.Uleb128put(dwarfctxt, fs, int64(0))                  // ...is CFA+0.
-	} else {
-		dwarf.Uleb128put(dwarfctxt, fs, int64(ctxt.Arch.PtrSize)) // ...plus the word size (because the call instruction implicitly adds one word to the frame).
-
-		fs.AddUint8(dwarf.DW_CFA_offset_extended)                                      // The previous value...
-		dwarf.Uleb128put(dwarfctxt, fs, int64(thearch.Dwarfreglr))                     // ...of the return address...
-		dwarf.Uleb128put(dwarfctxt, fs, int64(-ctxt.Arch.PtrSize)/dataAlignmentFactor) // ...is saved at [CFA - (PtrSize/4)].
-	}
-
-	pad := int64(cieReserve) + lengthFieldSize - fs.Size
-
-	if pad < 0 {
-		Exitf("dwarf: cieReserve too small by %d bytes.", -pad)
-	}
-
-	fs.AddBytes(zeros[:pad])
-
-	var deltaBuf []byte
-	pcsp := obj.NewPCIter(uint32(ctxt.Arch.MinLC))
-	for _, s := range ctxt.Textp {
-		if s.FuncInfo == nil {
-			continue
-		}
-
-		// Emit a FDE, Section 6.4.1.
-		// First build the section contents into a byte buffer.
-		deltaBuf = deltaBuf[:0]
-		if haslinkregister(ctxt) && s.Attr.TopFrame() {
-			// Mark the link register as having an undefined value.
-			// This stops call stack unwinders progressing any further.
-			// TODO: similar mark on non-LR architectures.
-			deltaBuf = append(deltaBuf, dwarf.DW_CFA_undefined)
-			deltaBuf = dwarf.AppendUleb128(deltaBuf, uint64(thearch.Dwarfreglr))
-		}
-		for pcsp.Init(s.FuncInfo.Pcsp.P); !pcsp.Done; pcsp.Next() {
-			nextpc := pcsp.NextPC
-
-			// pciterinit goes up to the end of the function,
-			// but DWARF expects us to stop just before the end.
-			if int64(nextpc) == s.Size {
-				nextpc--
-				if nextpc < pcsp.PC {
-					continue
-				}
-			}
-
-			spdelta := int64(pcsp.Value)
-			if !haslinkregister(ctxt) {
-				// Return address has been pushed onto stack.
-				spdelta += int64(ctxt.Arch.PtrSize)
-			}
-
-			if haslinkregister(ctxt) && !s.Attr.TopFrame() {
-				// TODO(bryanpkc): This is imprecise. In general, the instruction
-				// that stores the return address to the stack frame is not the
-				// same one that allocates the frame.
-				if pcsp.Value > 0 {
-					// The return address is preserved at (CFA-frame_size)
-					// after a stack frame has been allocated.
-					deltaBuf = append(deltaBuf, dwarf.DW_CFA_offset_extended_sf)
-					deltaBuf = dwarf.AppendUleb128(deltaBuf, uint64(thearch.Dwarfreglr))
-					deltaBuf = dwarf.AppendSleb128(deltaBuf, -spdelta/dataAlignmentFactor)
-				} else {
-					// The return address is restored into the link register
-					// when a stack frame has been de-allocated.
-					deltaBuf = append(deltaBuf, dwarf.DW_CFA_same_value)
-					deltaBuf = dwarf.AppendUleb128(deltaBuf, uint64(thearch.Dwarfreglr))
-				}
-			}
-
-			deltaBuf = appendPCDeltaCFA(ctxt.Arch, deltaBuf, int64(nextpc)-int64(pcsp.PC), spdelta)
-		}
-		pad := int(Rnd(int64(len(deltaBuf)), int64(ctxt.Arch.PtrSize))) - len(deltaBuf)
-		deltaBuf = append(deltaBuf, zeros[:pad]...)
-
-		// Emit the FDE header, Section 6.4.1.
-		//	4 bytes: length, must be multiple of thearch.ptrsize
-		//	4/8 bytes: Pointer to the CIE above, at offset 0
-		//	ptrsize: initial location
-		//	ptrsize: address range
-
-		fdeLength := uint64(4 + 2*ctxt.Arch.PtrSize + len(deltaBuf))
-		if isDwarf64(ctxt) {
-			fdeLength += 4 // 4 bytes added for CIE pointer
-		}
-		createUnitLength(ctxt, fs, fdeLength)
-
-		if ctxt.LinkMode == LinkExternal {
-			addDwarfAddrRef(ctxt, fs, fs)
-		} else {
-			addDwarfAddrField(ctxt, fs, 0) // CIE offset
-		}
-		fs.AddAddr(ctxt.Arch, s)
-		fs.AddUintXX(ctxt.Arch, uint64(s.Size), ctxt.Arch.PtrSize) // address range
-		fs.AddBytes(deltaBuf)
-
-		if ctxt.HeadType == objabi.Haix {
-			addDwsectCUSize(".debug_frame", s.File, fdeLength+uint64(lengthFieldSize))
-		}
-	}
-	return syms
-}
-
-/*
- *  Walk DWarfDebugInfoEntries, and emit .debug_info
- */
-const (
-	COMPUNITHEADERSIZE = 4 + 2 + 4 + 1
-)
-
-func writeinfo(ctxt *Link, syms []*sym.Symbol, units []*sym.CompilationUnit, abbrevsym *sym.Symbol, pubNames, pubTypes *pubWriter) []*sym.Symbol {
-	infosec := ctxt.Syms.Lookup(".debug_info", 0)
-	infosec.Type = sym.SDWARFINFO
-	infosec.Attr |= sym.AttrReachable
-	syms = append(syms, infosec)
-
-	var dwarfctxt dwarf.Context = dwctxt{ctxt}
-
-	for _, u := range units {
-		compunit := u.DWInfo
-		s := dtolsym(compunit.Sym)
-
-		if len(u.Textp) == 0 && u.DWInfo.Child == nil {
-			continue
-		}
-
-		pubNames.beginCompUnit(compunit)
-		pubTypes.beginCompUnit(compunit)
-
-		// Write .debug_info Compilation Unit Header (sec 7.5.1)
-		// Fields marked with (*) must be changed for 64-bit dwarf
-		// This must match COMPUNITHEADERSIZE above.
-		createUnitLength(ctxt, s, 0) // unit_length (*), will be filled in later.
-		s.AddUint16(ctxt.Arch, 4)    // dwarf version (appendix F)
-
-		// debug_abbrev_offset (*)
-		addDwarfAddrRef(ctxt, s, abbrevsym)
-
-		s.AddUint8(uint8(ctxt.Arch.PtrSize)) // address_size
-
-		dwarf.Uleb128put(dwarfctxt, s, int64(compunit.Abbrev))
-		dwarf.PutAttrs(dwarfctxt, s, compunit.Abbrev, compunit.Attr)
-
-		cu := []*sym.Symbol{s}
-		cu = append(cu, u.AbsFnDIEs...)
-		cu = append(cu, u.FuncDIEs...)
-		if u.Consts != nil {
-			cu = append(cu, u.Consts)
-		}
-		var cusize int64
-		for _, child := range cu {
-			cusize += child.Size
-		}
-
-		for die := compunit.Child; die != nil; die = die.Link {
-			l := len(cu)
-			lastSymSz := cu[l-1].Size
-			cu = putdie(ctxt, dwarfctxt, cu, die)
-			if ispubname(die) {
-				pubNames.add(die, cusize)
-			}
-			if ispubtype(die) {
-				pubTypes.add(die, cusize)
-			}
-			if lastSymSz != cu[l-1].Size {
-				// putdie will sometimes append directly to the last symbol of the list
-				cusize = cusize - lastSymSz + cu[l-1].Size
-			}
-			for _, child := range cu[l:] {
-				cusize += child.Size
-			}
-		}
-		cu[len(cu)-1].AddUint8(0) // closes compilation unit DIE
-		cusize++
-
-		// Save size for AIX symbol table.
-		if ctxt.HeadType == objabi.Haix {
-			saveDwsectCUSize(".debug_info", getPkgFromCUSym(s), uint64(cusize))
-		}
-		if isDwarf64(ctxt) {
-			cusize -= 12                            // exclude the length field.
-			s.SetUint(ctxt.Arch, 4, uint64(cusize)) // 4 because of 0XFFFFFFFF
-		} else {
-			cusize -= 4 // exclude the length field.
-			s.SetUint32(ctxt.Arch, 0, uint32(cusize))
-		}
-		pubNames.endCompUnit(compunit, uint32(cusize)+4)
-		pubTypes.endCompUnit(compunit, uint32(cusize)+4)
-		syms = append(syms, cu...)
-	}
-	return syms
-}
-
-/*
- *  Emit .debug_pubnames/_types.  _info must have been written before,
- *  because we need die->offs and infoo/infosize;
- */
-func ispubname(die *dwarf.DWDie) bool {
-	switch die.Abbrev {
-	case dwarf.DW_ABRV_FUNCTION, dwarf.DW_ABRV_VARIABLE:
-		a := getattr(die, dwarf.DW_AT_external)
-		return a != nil && a.Value != 0
-	}
-
-	return false
-}
-
-func ispubtype(die *dwarf.DWDie) bool {
-	return die.Abbrev >= dwarf.DW_ABRV_NULLTYPE
-}
-
-type pubWriter struct {
-	ctxt  *Link
-	s     *sym.Symbol
-	sname string
-
-	sectionstart int64
-	culengthOff  int64
-}
-
-func newPubWriter(ctxt *Link, sname string) *pubWriter {
-	s := ctxt.Syms.Lookup(sname, 0)
-	s.Type = sym.SDWARFSECT
-	return &pubWriter{ctxt: ctxt, s: s, sname: sname}
-}
-
-func (pw *pubWriter) beginCompUnit(compunit *dwarf.DWDie) {
-	pw.sectionstart = pw.s.Size
-
-	// Write .debug_pubnames/types	Header (sec 6.1.1)
-	createUnitLength(pw.ctxt, pw.s, 0)                    // unit_length (*), will be filled in later.
-	pw.s.AddUint16(pw.ctxt.Arch, 2)                       // dwarf version (appendix F)
-	addDwarfAddrRef(pw.ctxt, pw.s, dtolsym(compunit.Sym)) // debug_info_offset (of the Comp unit Header)
-	pw.culengthOff = pw.s.Size
-	addDwarfAddrField(pw.ctxt, pw.s, uint64(0)) // debug_info_length, will be filled in later.
-
-}
-
-func (pw *pubWriter) add(die *dwarf.DWDie, offset int64) {
-	dwa := getattr(die, dwarf.DW_AT_name)
-	name := dwa.Data.(string)
-	if die.Sym == nil {
-		fmt.Println("Missing sym for ", name)
-	}
-	addDwarfAddrField(pw.ctxt, pw.s, uint64(offset))
-	Addstring(pw.s, name)
-}
-
-func (pw *pubWriter) endCompUnit(compunit *dwarf.DWDie, culength uint32) {
-	addDwarfAddrField(pw.ctxt, pw.s, 0) // Null offset
-
-	// On AIX, save the current size of this compilation unit.
-	if pw.ctxt.HeadType == objabi.Haix {
-		saveDwsectCUSize(pw.sname, getPkgFromCUSym(dtolsym(compunit.Sym)), uint64(pw.s.Size-pw.sectionstart))
-	}
-	if isDwarf64(pw.ctxt) {
-		pw.s.SetUint(pw.ctxt.Arch, pw.sectionstart+4, uint64(pw.s.Size-pw.sectionstart)-12) // exclude the length field.
-		pw.s.SetUint(pw.ctxt.Arch, pw.culengthOff, uint64(culength))
-	} else {
-		pw.s.SetUint32(pw.ctxt.Arch, pw.sectionstart, uint32(pw.s.Size-pw.sectionstart)-4) // exclude the length field.
-		pw.s.SetUint32(pw.ctxt.Arch, pw.culengthOff, culength)
-	}
-}
-
-func writegdbscript(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
-	// TODO (aix): make it available
-	if ctxt.HeadType == objabi.Haix {
-		return syms
-	}
-	if ctxt.LinkMode == LinkExternal && ctxt.HeadType == objabi.Hwindows && ctxt.BuildMode == BuildModeCArchive {
-		// gcc on Windows places .debug_gdb_scripts in the wrong location, which
-		// causes the program not to run. See https://golang.org/issue/20183
-		// Non c-archives can avoid this issue via a linker script
-		// (see fix near writeGDBLinkerScript).
-		// c-archive users would need to specify the linker script manually.
-		// For UX it's better not to deal with this.
-		return syms
-	}
-
-	if gdbscript != "" {
-		s := ctxt.Syms.Lookup(".debug_gdb_scripts", 0)
-		s.Type = sym.SDWARFSECT
-		syms = append(syms, s)
-		s.AddUint8(1) // magic 1 byte?
-		Addstring(s, gdbscript)
-	}
-
-	return syms
-}
-
-var prototypedies map[string]*dwarf.DWDie
-
-func dwarfEnabled(ctxt *Link) bool {
-	if *FlagW { // disable dwarf
-		return false
-	}
-	if *FlagS && ctxt.HeadType != objabi.Hdarwin {
-		return false
-	}
-	if ctxt.HeadType == objabi.Hplan9 || ctxt.HeadType == objabi.Hjs {
-		return false
-	}
-
-	if ctxt.LinkMode == LinkExternal {
-		switch {
-		case ctxt.IsELF:
-		case ctxt.HeadType == objabi.Hdarwin:
-		case ctxt.HeadType == objabi.Hwindows:
-		case ctxt.HeadType == objabi.Haix:
-			res, err := dwarf.IsDWARFEnabledOnAIXLd(ctxt.extld())
-			if err != nil {
-				Exitf("%v", err)
-			}
-			return res
-		default:
-			return false
-		}
-	}
-
-	return true
-}
-
-// dwarfGenerateDebugInfo generated debug info entries for all types,
-// variables and functions in the program.
-// Along with dwarfGenerateDebugSyms they are the two main entry points into
-// dwarf generation: dwarfGenerateDebugInfo does all the work that should be
-// done before symbol names are mangled while dwarfgeneratedebugsyms does
-// all the work that can only be done after addresses have been assigned to
-// text symbols.
-func dwarfGenerateDebugInfo(ctxt *Link) {
-	if !dwarfEnabled(ctxt) {
-		return
-	}
-
-	if ctxt.HeadType == objabi.Haix {
-		// Initial map used to store package size for each DWARF section.
-		dwsectCUSize = make(map[string]uint64)
-	}
-
-	// Forctxt.Diagnostic messages.
-	newattr(&dwtypes, dwarf.DW_AT_name, dwarf.DW_CLS_STRING, int64(len("dwtypes")), "dwtypes")
-
-	// Some types that must exist to define other ones.
-	newdie(ctxt, &dwtypes, dwarf.DW_ABRV_NULLTYPE, "<unspecified>", 0)
-
-	newdie(ctxt, &dwtypes, dwarf.DW_ABRV_NULLTYPE, "void", 0)
-	newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer", 0)
-
-	die := newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, "uintptr", 0) // needed for array size
-	newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_unsigned, 0)
-	newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(ctxt.Arch.PtrSize), 0)
-	newattr(die, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, objabi.KindUintptr, 0)
-	newattr(die, dwarf.DW_AT_go_runtime_type, dwarf.DW_CLS_ADDRESS, 0, lookupOrDiag(ctxt, "type.uintptr"))
-
-	// Prototypes needed for type synthesis.
-	prototypedies = map[string]*dwarf.DWDie{
-		"type.runtime.stringStructDWARF": nil,
-		"type.runtime.slice":             nil,
-		"type.runtime.hmap":              nil,
-		"type.runtime.bmap":              nil,
-		"type.runtime.sudog":             nil,
-		"type.runtime.waitq":             nil,
-		"type.runtime.hchan":             nil,
-	}
-
-	// Needed by the prettyprinter code for interface inspection.
-	for _, typ := range []string{
-		"type.runtime._type",
-		"type.runtime.arraytype",
-		"type.runtime.chantype",
-		"type.runtime.functype",
-		"type.runtime.maptype",
-		"type.runtime.ptrtype",
-		"type.runtime.slicetype",
-		"type.runtime.structtype",
-		"type.runtime.interfacetype",
-		"type.runtime.itab",
-		"type.runtime.imethod"} {
-		defgotype(ctxt, lookupOrDiag(ctxt, typ))
-	}
-
-	// fake root DIE for compile unit DIEs
-	var dwroot dwarf.DWDie
-	flagVariants := make(map[string]bool)
-
-	for _, lib := range ctxt.Library {
-		consts := ctxt.Syms.ROLookup(dwarf.ConstInfoPrefix+lib.Pkg, 0)
-		for _, unit := range lib.Units {
-			// We drop the constants into the first CU.
-			if consts != nil {
-				importInfoSymbol(ctxt, consts)
-				unit.Consts = consts
-				consts = nil
-			}
-
-			ctxt.compUnits = append(ctxt.compUnits, unit)
-
-			// We need at least one runtime unit.
-			if unit.Lib.Pkg == "runtime" {
-				ctxt.runtimeCU = unit
-			}
-
-			unit.DWInfo = newdie(ctxt, &dwroot, dwarf.DW_ABRV_COMPUNIT, unit.Lib.Pkg, 0)
-			newattr(unit.DWInfo, dwarf.DW_AT_language, dwarf.DW_CLS_CONSTANT, int64(dwarf.DW_LANG_Go), 0)
-			// OS X linker requires compilation dir or absolute path in comp unit name to output debug info.
-			compDir := getCompilationDir()
-			// TODO: Make this be the actual compilation directory, not
-			// the linker directory. If we move CU construction into the
-			// compiler, this should happen naturally.
-			newattr(unit.DWInfo, dwarf.DW_AT_comp_dir, dwarf.DW_CLS_STRING, int64(len(compDir)), compDir)
-			producerExtra := ctxt.Syms.Lookup(dwarf.CUInfoPrefix+"producer."+unit.Lib.Pkg, 0)
-			producer := "Go cmd/compile " + objabi.Version
-			if len(producerExtra.P) > 0 {
-				// We put a semicolon before the flags to clearly
-				// separate them from the version, which can be long
-				// and have lots of weird things in it in development
-				// versions. We promise not to put a semicolon in the
-				// version, so it should be safe for readers to scan
-				// forward to the semicolon.
-				producer += "; " + string(producerExtra.P)
-				flagVariants[string(producerExtra.P)] = true
-			} else {
-				flagVariants[""] = true
-			}
-
-			newattr(unit.DWInfo, dwarf.DW_AT_producer, dwarf.DW_CLS_STRING, int64(len(producer)), producer)
-
-			var pkgname string
-			if s := ctxt.Syms.ROLookup(dwarf.CUInfoPrefix+"packagename."+unit.Lib.Pkg, 0); s != nil {
-				pkgname = string(s.P)
-			}
-			newattr(unit.DWInfo, dwarf.DW_AT_go_package_name, dwarf.DW_CLS_STRING, int64(len(pkgname)), pkgname)
-
-			if len(unit.Textp) == 0 {
-				unit.DWInfo.Abbrev = dwarf.DW_ABRV_COMPUNIT_TEXTLESS
-			}
-
-			// Scan all functions in this compilation unit, create DIEs for all
-			// referenced types, create the file table for debug_line, find all
-			// referenced abstract functions.
-			// Collect all debug_range symbols in unit.rangeSyms
-			for _, s := range unit.Textp { // textp has been dead-code-eliminated already.
-				dsym := dwarfFuncSym(ctxt, s, dwarf.InfoPrefix, false)
-				dsym.Attr |= sym.AttrNotInSymbolTable | sym.AttrReachable
-				dsym.Type = sym.SDWARFINFO
-				unit.FuncDIEs = append(unit.FuncDIEs, dsym)
-
-				rangeSym := dwarfFuncSym(ctxt, s, dwarf.RangePrefix, false)
-				if rangeSym != nil && rangeSym.Size > 0 {
-					rangeSym.Attr |= sym.AttrReachable | sym.AttrNotInSymbolTable
-					rangeSym.Type = sym.SDWARFRANGE
-					if ctxt.HeadType == objabi.Haix {
-						addDwsectCUSize(".debug_ranges", unit.Lib.Pkg, uint64(rangeSym.Size))
-					}
-					unit.RangeSyms = append(unit.RangeSyms, rangeSym)
-				}
-
-				for ri := 0; ri < len(dsym.R); ri++ {
-					r := &dsym.R[ri]
-					if r.Type == objabi.R_DWARFSECREF {
-						rsym := r.Sym
-						if strings.HasPrefix(rsym.Name, dwarf.InfoPrefix) && strings.HasSuffix(rsym.Name, dwarf.AbstractFuncSuffix) && !rsym.Attr.OnList() {
-							// abstract function
-							rsym.Attr |= sym.AttrOnList
-							unit.AbsFnDIEs = append(unit.AbsFnDIEs, rsym)
-							importInfoSymbol(ctxt, rsym)
-						} else if rsym.Size == 0 {
-							// a type we do not have a DIE for
-							n := nameFromDIESym(rsym)
-							defgotype(ctxt, ctxt.Syms.Lookup("type."+n, 0))
-						}
-					}
-				}
-			}
-		}
-	}
-
-	// Fix for 31034: if the objects feeding into this link were compiled
-	// with different sets of flags, then don't issue an error if
-	// the -strictdups checks fail.
-	if checkStrictDups > 1 && len(flagVariants) > 1 {
-		checkStrictDups = 1
-	}
-
-	// Create DIEs for global variables and the types they use.
-	genasmsym(ctxt, defdwsymb)
-
-	// Create DIEs for variable types indirectly referenced by function
-	// autos (which may not appear directly as param/var DIEs).
-	for _, lib := range ctxt.Library {
-		for _, unit := range lib.Units {
-			lists := [][]*sym.Symbol{unit.AbsFnDIEs, unit.FuncDIEs}
-			for _, list := range lists {
-				for _, s := range list {
-					for i := 0; i < len(s.R); i++ {
-						r := &s.R[i]
-						if r.Type == objabi.R_USETYPE {
-							defgotype(ctxt, r.Sym)
-						}
-					}
-				}
-			}
-		}
-	}
-
-	synthesizestringtypes(ctxt, dwtypes.Child)
-	synthesizeslicetypes(ctxt, dwtypes.Child)
-	synthesizemaptypes(ctxt, dwtypes.Child)
-	synthesizechantypes(ctxt, dwtypes.Child)
-}
-
-// dwarfGenerateDebugSyms constructs debug_line, debug_frame, debug_loc,
-// debug_pubnames and debug_pubtypes. It also writes out the debug_info
-// section using symbols generated in dwarfGenerateDebugInfo.
-func dwarfGenerateDebugSyms(ctxt *Link) {
-	if !dwarfEnabled(ctxt) {
-		return
-	}
-
-	abbrev := writeabbrev(ctxt)
-	syms := []*sym.Symbol{abbrev}
-
-	calcCompUnitRanges(ctxt)
-	sort.Sort(compilationUnitByStartPC(ctxt.compUnits))
-
-	// Write per-package line and range tables and start their CU DIEs.
-	debugLine := ctxt.Syms.Lookup(".debug_line", 0)
-	debugLine.Type = sym.SDWARFSECT
-	debugRanges := ctxt.Syms.Lookup(".debug_ranges", 0)
-	debugRanges.Type = sym.SDWARFRANGE
-	debugRanges.Attr |= sym.AttrReachable
-	syms = append(syms, debugLine)
-	for _, u := range ctxt.compUnits {
-		reversetree(&u.DWInfo.Child)
-		if u.DWInfo.Abbrev == dwarf.DW_ABRV_COMPUNIT_TEXTLESS {
-			continue
-		}
-		writelines(ctxt, u, debugLine)
-		writepcranges(ctxt, u, u.Textp[0], u.PCs, debugRanges)
-	}
-
-	// newdie adds DIEs to the *beginning* of the parent's DIE list.
-	// Now that we're done creating DIEs, reverse the trees so DIEs
-	// appear in the order they were created.
-	reversetree(&dwtypes.Child)
-	movetomodule(ctxt, &dwtypes)
-
-	pubNames := newPubWriter(ctxt, ".debug_pubnames")
-	pubTypes := newPubWriter(ctxt, ".debug_pubtypes")
-
-	// Need to reorder symbols so sym.SDWARFINFO is after all sym.SDWARFSECT
-	infosyms := writeinfo(ctxt, nil, ctxt.compUnits, abbrev, pubNames, pubTypes)
-
-	syms = writeframes(ctxt, syms)
-	syms = append(syms, pubNames.s, pubTypes.s)
-	syms = writegdbscript(ctxt, syms)
-	// Now we're done writing SDWARFSECT symbols, so we can write
-	// other SDWARF* symbols.
-	syms = append(syms, infosyms...)
-	syms = collectlocs(ctxt, syms, ctxt.compUnits)
-	syms = append(syms, debugRanges)
-	for _, unit := range ctxt.compUnits {
-		syms = append(syms, unit.RangeSyms...)
-	}
-	dwarfp = syms
-}
-
-func collectlocs(ctxt *Link, syms []*sym.Symbol, units []*sym.CompilationUnit) []*sym.Symbol {
-	empty := true
-	for _, u := range units {
-		for _, fn := range u.FuncDIEs {
-			for i := range fn.R {
-				reloc := &fn.R[i] // Copying sym.Reloc has measurable impact on performance
-				if reloc.Type == objabi.R_DWARFSECREF && strings.HasPrefix(reloc.Sym.Name, dwarf.LocPrefix) {
-					reloc.Sym.Attr |= sym.AttrReachable | sym.AttrNotInSymbolTable
-					syms = append(syms, reloc.Sym)
-					empty = false
-					// One location list entry per function, but many relocations to it. Don't duplicate.
-					break
-				}
-			}
-		}
-	}
-	// Don't emit .debug_loc if it's empty -- it makes the ARM linker mad.
-	if !empty {
-		locsym := ctxt.Syms.Lookup(".debug_loc", 0)
-		locsym.Type = sym.SDWARFLOC
-		locsym.Attr |= sym.AttrReachable
-		syms = append(syms, locsym)
-	}
-	return syms
-}
-
-// Read a pointer-sized uint from the beginning of buf.
-func readPtr(ctxt *Link, buf []byte) uint64 {
-	switch ctxt.Arch.PtrSize {
-	case 4:
-		return uint64(ctxt.Arch.ByteOrder.Uint32(buf))
-	case 8:
-		return ctxt.Arch.ByteOrder.Uint64(buf)
-	default:
-		panic("unexpected pointer size")
-	}
-}
-
-/*
- *  Elf.
- */
-func dwarfaddshstrings(ctxt *Link, shstrtab *sym.Symbol) {
-	if *FlagW { // disable dwarf
-		return
-	}
-
-	secs := []string{"abbrev", "frame", "info", "loc", "line", "pubnames", "pubtypes", "gdb_scripts", "ranges"}
-	for _, sec := range secs {
-		Addstring(shstrtab, ".debug_"+sec)
-		if ctxt.LinkMode == LinkExternal {
-			Addstring(shstrtab, elfRelType+".debug_"+sec)
-		} else {
-			Addstring(shstrtab, ".zdebug_"+sec)
-		}
-	}
-}
-
-// Add section symbols for DWARF debug info.  This is called before
-// dwarfaddelfheaders.
-func dwarfaddelfsectionsyms(ctxt *Link) {
-	if *FlagW { // disable dwarf
-		return
-	}
-	if ctxt.LinkMode != LinkExternal {
-		return
-	}
-
-	s := ctxt.Syms.Lookup(".debug_info", 0)
-	putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
-	s = ctxt.Syms.Lookup(".debug_abbrev", 0)
-	putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
-	s = ctxt.Syms.Lookup(".debug_line", 0)
-	putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
-	s = ctxt.Syms.Lookup(".debug_frame", 0)
-	putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
-	s = ctxt.Syms.Lookup(".debug_loc", 0)
-	if s.Sect != nil {
-		putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
-	}
-	s = ctxt.Syms.Lookup(".debug_ranges", 0)
-	if s.Sect != nil {
-		putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
-	}
-}
-
-// dwarfcompress compresses the DWARF sections. Relocations are applied
-// on the fly. After this, dwarfp will contain a different (new) set of
-// symbols, and sections may have been replaced.
-func dwarfcompress(ctxt *Link) {
-	supported := ctxt.IsELF || ctxt.HeadType == objabi.Hwindows || ctxt.HeadType == objabi.Hdarwin
-	if !ctxt.compressDWARF || !supported || ctxt.LinkMode != LinkInternal {
-		return
-	}
-
-	var start int
-	var newDwarfp []*sym.Symbol
-	Segdwarf.Sections = Segdwarf.Sections[:0]
-	for i, s := range dwarfp {
-		// Find the boundaries between sections and compress
-		// the whole section once we've found the last of its
-		// symbols.
-		if i+1 >= len(dwarfp) || s.Sect != dwarfp[i+1].Sect {
-			s1 := compressSyms(ctxt, dwarfp[start:i+1])
-			if s1 == nil {
-				// Compression didn't help.
-				newDwarfp = append(newDwarfp, dwarfp[start:i+1]...)
-				Segdwarf.Sections = append(Segdwarf.Sections, s.Sect)
-			} else {
-				compressedSegName := ".zdebug_" + s.Sect.Name[len(".debug_"):]
-				sect := addsection(ctxt.Arch, &Segdwarf, compressedSegName, 04)
-				sect.Length = uint64(len(s1))
-				newSym := ctxt.Syms.Lookup(compressedSegName, 0)
-				newSym.P = s1
-				newSym.Size = int64(len(s1))
-				newSym.Sect = sect
-				newDwarfp = append(newDwarfp, newSym)
-			}
-			start = i + 1
-		}
-	}
-	dwarfp = newDwarfp
-	ctxt.relocbuf = nil // no longer needed, don't hold it live
-
-	// Re-compute the locations of the compressed DWARF symbols
-	// and sections, since the layout of these within the file is
-	// based on Section.Vaddr and Symbol.Value.
-	pos := Segdwarf.Vaddr
-	var prevSect *sym.Section
-	for _, s := range dwarfp {
-		s.Value = int64(pos)
-		if s.Sect != prevSect {
-			s.Sect.Vaddr = uint64(s.Value)
-			prevSect = s.Sect
-		}
-		if s.Sub != nil {
-			log.Fatalf("%s: unexpected sub-symbols", s)
-		}
-		pos += uint64(s.Size)
-		if ctxt.HeadType == objabi.Hwindows {
-			pos = uint64(Rnd(int64(pos), PEFILEALIGN))
-		}
-
-	}
-	Segdwarf.Length = pos - Segdwarf.Vaddr
-}
-
-type compilationUnitByStartPC []*sym.CompilationUnit
-
-func (v compilationUnitByStartPC) Len() int      { return len(v) }
-func (v compilationUnitByStartPC) Swap(i, j int) { v[i], v[j] = v[j], v[i] }
-
-func (v compilationUnitByStartPC) Less(i, j int) bool {
-	switch {
-	case len(v[i].Textp) == 0 && len(v[j].Textp) == 0:
-		return v[i].Lib.Pkg < v[j].Lib.Pkg
-	case len(v[i].Textp) != 0 && len(v[j].Textp) == 0:
-		return true
-	case len(v[i].Textp) == 0 && len(v[j].Textp) != 0:
-		return false
-	default:
-		return v[i].Textp[0].Value < v[j].Textp[0].Value
-	}
-}
-
-// On AIX, the symbol table needs to know where are the compilation units parts
-// for a specific package in each .dw section.
-// dwsectCUSize map will save the size of a compilation unit for
-// the corresponding .dw section.
-// This size can later be retrieved with the index "sectionName.pkgName".
-var dwsectCUSize map[string]uint64
-
-// getDwsectCUSize retrieves the corresponding package size inside the current section.
-func getDwsectCUSize(sname string, pkgname string) uint64 {
-	return dwsectCUSize[sname+"."+pkgname]
-}
-
-func saveDwsectCUSize(sname string, pkgname string, size uint64) {
-	dwsectCUSize[sname+"."+pkgname] = size
-}
-
-func addDwsectCUSize(sname string, pkgname string, size uint64) {
-	dwsectCUSize[sname+"."+pkgname] += size
-}
-
-// getPkgFromCUSym returns the package name for the compilation unit
-// represented by s.
-// The prefix dwarf.InfoPrefix+".pkg." needs to be removed in order to get
-// the package name.
-func getPkgFromCUSym(s *sym.Symbol) string {
-	return strings.TrimPrefix(s.Name, dwarf.InfoPrefix+".pkg.")
-}
diff --git a/src/cmd/oldlink/internal/ld/elf.go b/src/cmd/oldlink/internal/ld/elf.go
deleted file mode 100644
index 28cab75..0000000
--- a/src/cmd/oldlink/internal/ld/elf.go
+++ /dev/null
@@ -1,2448 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ld
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/sym"
-	"crypto/sha1"
-	"encoding/binary"
-	"encoding/hex"
-	"io"
-	"path/filepath"
-	"sort"
-	"strings"
-)
-
-/*
- * Derived from:
- * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $
- * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $
- * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $
- * $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $
- * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $
- * $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $
- * $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $
- * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $
- * $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $
- *
- * Copyright (c) 1996-1998 John D. Polstra.  All rights reserved.
- * Copyright (c) 2001 David E. O'Brien
- * Portions Copyright 2009 The Go Authors. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-/*
- * ELF definitions that are independent of architecture or word size.
- */
-
-/*
- * Note header.  The ".note" section contains an array of notes.  Each
- * begins with this header, aligned to a word boundary.  Immediately
- * following the note header is n_namesz bytes of name, padded to the
- * next word boundary.  Then comes n_descsz bytes of descriptor, again
- * padded to a word boundary.  The values of n_namesz and n_descsz do
- * not include the padding.
- */
-type elfNote struct {
-	nNamesz uint32
-	nDescsz uint32
-	nType   uint32
-}
-
-const (
-	EI_MAG0              = 0
-	EI_MAG1              = 1
-	EI_MAG2              = 2
-	EI_MAG3              = 3
-	EI_CLASS             = 4
-	EI_DATA              = 5
-	EI_VERSION           = 6
-	EI_OSABI             = 7
-	EI_ABIVERSION        = 8
-	OLD_EI_BRAND         = 8
-	EI_PAD               = 9
-	EI_NIDENT            = 16
-	ELFMAG0              = 0x7f
-	ELFMAG1              = 'E'
-	ELFMAG2              = 'L'
-	ELFMAG3              = 'F'
-	SELFMAG              = 4
-	EV_NONE              = 0
-	EV_CURRENT           = 1
-	ELFCLASSNONE         = 0
-	ELFCLASS32           = 1
-	ELFCLASS64           = 2
-	ELFDATANONE          = 0
-	ELFDATA2LSB          = 1
-	ELFDATA2MSB          = 2
-	ELFOSABI_NONE        = 0
-	ELFOSABI_HPUX        = 1
-	ELFOSABI_NETBSD      = 2
-	ELFOSABI_LINUX       = 3
-	ELFOSABI_HURD        = 4
-	ELFOSABI_86OPEN      = 5
-	ELFOSABI_SOLARIS     = 6
-	ELFOSABI_AIX         = 7
-	ELFOSABI_IRIX        = 8
-	ELFOSABI_FREEBSD     = 9
-	ELFOSABI_TRU64       = 10
-	ELFOSABI_MODESTO     = 11
-	ELFOSABI_OPENBSD     = 12
-	ELFOSABI_OPENVMS     = 13
-	ELFOSABI_NSK         = 14
-	ELFOSABI_ARM         = 97
-	ELFOSABI_STANDALONE  = 255
-	ELFOSABI_SYSV        = ELFOSABI_NONE
-	ELFOSABI_MONTEREY    = ELFOSABI_AIX
-	ET_NONE              = 0
-	ET_REL               = 1
-	ET_EXEC              = 2
-	ET_DYN               = 3
-	ET_CORE              = 4
-	ET_LOOS              = 0xfe00
-	ET_HIOS              = 0xfeff
-	ET_LOPROC            = 0xff00
-	ET_HIPROC            = 0xffff
-	EM_NONE              = 0
-	EM_M32               = 1
-	EM_SPARC             = 2
-	EM_386               = 3
-	EM_68K               = 4
-	EM_88K               = 5
-	EM_860               = 7
-	EM_MIPS              = 8
-	EM_S370              = 9
-	EM_MIPS_RS3_LE       = 10
-	EM_PARISC            = 15
-	EM_VPP500            = 17
-	EM_SPARC32PLUS       = 18
-	EM_960               = 19
-	EM_PPC               = 20
-	EM_PPC64             = 21
-	EM_S390              = 22
-	EM_V800              = 36
-	EM_FR20              = 37
-	EM_RH32              = 38
-	EM_RCE               = 39
-	EM_ARM               = 40
-	EM_SH                = 42
-	EM_SPARCV9           = 43
-	EM_TRICORE           = 44
-	EM_ARC               = 45
-	EM_H8_300            = 46
-	EM_H8_300H           = 47
-	EM_H8S               = 48
-	EM_H8_500            = 49
-	EM_IA_64             = 50
-	EM_MIPS_X            = 51
-	EM_COLDFIRE          = 52
-	EM_68HC12            = 53
-	EM_MMA               = 54
-	EM_PCP               = 55
-	EM_NCPU              = 56
-	EM_NDR1              = 57
-	EM_STARCORE          = 58
-	EM_ME16              = 59
-	EM_ST100             = 60
-	EM_TINYJ             = 61
-	EM_X86_64            = 62
-	EM_AARCH64           = 183
-	EM_486               = 6
-	EM_MIPS_RS4_BE       = 10
-	EM_ALPHA_STD         = 41
-	EM_ALPHA             = 0x9026
-	EM_RISCV             = 243
-	SHN_UNDEF            = 0
-	SHN_LORESERVE        = 0xff00
-	SHN_LOPROC           = 0xff00
-	SHN_HIPROC           = 0xff1f
-	SHN_LOOS             = 0xff20
-	SHN_HIOS             = 0xff3f
-	SHN_ABS              = 0xfff1
-	SHN_COMMON           = 0xfff2
-	SHN_XINDEX           = 0xffff
-	SHN_HIRESERVE        = 0xffff
-	SHT_NULL             = 0
-	SHT_PROGBITS         = 1
-	SHT_SYMTAB           = 2
-	SHT_STRTAB           = 3
-	SHT_RELA             = 4
-	SHT_HASH             = 5
-	SHT_DYNAMIC          = 6
-	SHT_NOTE             = 7
-	SHT_NOBITS           = 8
-	SHT_REL              = 9
-	SHT_SHLIB            = 10
-	SHT_DYNSYM           = 11
-	SHT_INIT_ARRAY       = 14
-	SHT_FINI_ARRAY       = 15
-	SHT_PREINIT_ARRAY    = 16
-	SHT_GROUP            = 17
-	SHT_SYMTAB_SHNDX     = 18
-	SHT_LOOS             = 0x60000000
-	SHT_HIOS             = 0x6fffffff
-	SHT_GNU_VERDEF       = 0x6ffffffd
-	SHT_GNU_VERNEED      = 0x6ffffffe
-	SHT_GNU_VERSYM       = 0x6fffffff
-	SHT_LOPROC           = 0x70000000
-	SHT_ARM_ATTRIBUTES   = 0x70000003
-	SHT_HIPROC           = 0x7fffffff
-	SHT_LOUSER           = 0x80000000
-	SHT_HIUSER           = 0xffffffff
-	SHF_WRITE            = 0x1
-	SHF_ALLOC            = 0x2
-	SHF_EXECINSTR        = 0x4
-	SHF_MERGE            = 0x10
-	SHF_STRINGS          = 0x20
-	SHF_INFO_LINK        = 0x40
-	SHF_LINK_ORDER       = 0x80
-	SHF_OS_NONCONFORMING = 0x100
-	SHF_GROUP            = 0x200
-	SHF_TLS              = 0x400
-	SHF_MASKOS           = 0x0ff00000
-	SHF_MASKPROC         = 0xf0000000
-	PT_NULL              = 0
-	PT_LOAD              = 1
-	PT_DYNAMIC           = 2
-	PT_INTERP            = 3
-	PT_NOTE              = 4
-	PT_SHLIB             = 5
-	PT_PHDR              = 6
-	PT_TLS               = 7
-	PT_LOOS              = 0x60000000
-	PT_HIOS              = 0x6fffffff
-	PT_LOPROC            = 0x70000000
-	PT_HIPROC            = 0x7fffffff
-	PT_GNU_STACK         = 0x6474e551
-	PT_GNU_RELRO         = 0x6474e552
-	PT_PAX_FLAGS         = 0x65041580
-	PT_SUNWSTACK         = 0x6ffffffb
-	PF_X                 = 0x1
-	PF_W                 = 0x2
-	PF_R                 = 0x4
-	PF_MASKOS            = 0x0ff00000
-	PF_MASKPROC          = 0xf0000000
-	DT_NULL              = 0
-	DT_NEEDED            = 1
-	DT_PLTRELSZ          = 2
-	DT_PLTGOT            = 3
-	DT_HASH              = 4
-	DT_STRTAB            = 5
-	DT_SYMTAB            = 6
-	DT_RELA              = 7
-	DT_RELASZ            = 8
-	DT_RELAENT           = 9
-	DT_STRSZ             = 10
-	DT_SYMENT            = 11
-	DT_INIT              = 12
-	DT_FINI              = 13
-	DT_SONAME            = 14
-	DT_RPATH             = 15
-	DT_SYMBOLIC          = 16
-	DT_REL               = 17
-	DT_RELSZ             = 18
-	DT_RELENT            = 19
-	DT_PLTREL            = 20
-	DT_DEBUG             = 21
-	DT_TEXTREL           = 22
-	DT_JMPREL            = 23
-	DT_BIND_NOW          = 24
-	DT_INIT_ARRAY        = 25
-	DT_FINI_ARRAY        = 26
-	DT_INIT_ARRAYSZ      = 27
-	DT_FINI_ARRAYSZ      = 28
-	DT_RUNPATH           = 29
-	DT_FLAGS             = 30
-	DT_ENCODING          = 32
-	DT_PREINIT_ARRAY     = 32
-	DT_PREINIT_ARRAYSZ   = 33
-	DT_LOOS              = 0x6000000d
-	DT_HIOS              = 0x6ffff000
-	DT_LOPROC            = 0x70000000
-	DT_HIPROC            = 0x7fffffff
-	DT_VERNEED           = 0x6ffffffe
-	DT_VERNEEDNUM        = 0x6fffffff
-	DT_VERSYM            = 0x6ffffff0
-	DT_PPC64_GLINK       = DT_LOPROC + 0
-	DT_PPC64_OPT         = DT_LOPROC + 3
-	DF_ORIGIN            = 0x0001
-	DF_SYMBOLIC          = 0x0002
-	DF_TEXTREL           = 0x0004
-	DF_BIND_NOW          = 0x0008
-	DF_STATIC_TLS        = 0x0010
-	NT_PRSTATUS          = 1
-	NT_FPREGSET          = 2
-	NT_PRPSINFO          = 3
-	STB_LOCAL            = 0
-	STB_GLOBAL           = 1
-	STB_WEAK             = 2
-	STB_LOOS             = 10
-	STB_HIOS             = 12
-	STB_LOPROC           = 13
-	STB_HIPROC           = 15
-	STT_NOTYPE           = 0
-	STT_OBJECT           = 1
-	STT_FUNC             = 2
-	STT_SECTION          = 3
-	STT_FILE             = 4
-	STT_COMMON           = 5
-	STT_TLS              = 6
-	STT_LOOS             = 10
-	STT_HIOS             = 12
-	STT_LOPROC           = 13
-	STT_HIPROC           = 15
-	STV_DEFAULT          = 0x0
-	STV_INTERNAL         = 0x1
-	STV_HIDDEN           = 0x2
-	STV_PROTECTED        = 0x3
-	STN_UNDEF            = 0
-)
-
-/* For accessing the fields of r_info. */
-
-/* For constructing r_info from field values. */
-
-/*
- * Relocation types.
- */
-const (
-	ARM_MAGIC_TRAMP_NUMBER = 0x5c000003
-)
-
-/*
- * Symbol table entries.
- */
-
-/* For accessing the fields of st_info. */
-
-/* For constructing st_info from field values. */
-
-/* For accessing the fields of st_other. */
-
-/*
- * ELF header.
- */
-type ElfEhdr struct {
-	ident     [EI_NIDENT]uint8
-	type_     uint16
-	machine   uint16
-	version   uint32
-	entry     uint64
-	phoff     uint64
-	shoff     uint64
-	flags     uint32
-	ehsize    uint16
-	phentsize uint16
-	phnum     uint16
-	shentsize uint16
-	shnum     uint16
-	shstrndx  uint16
-}
-
-/*
- * Section header.
- */
-type ElfShdr struct {
-	name      uint32
-	type_     uint32
-	flags     uint64
-	addr      uint64
-	off       uint64
-	size      uint64
-	link      uint32
-	info      uint32
-	addralign uint64
-	entsize   uint64
-	shnum     int
-}
-
-/*
- * Program header.
- */
-type ElfPhdr struct {
-	type_  uint32
-	flags  uint32
-	off    uint64
-	vaddr  uint64
-	paddr  uint64
-	filesz uint64
-	memsz  uint64
-	align  uint64
-}
-
-/* For accessing the fields of r_info. */
-
-/* For constructing r_info from field values. */
-
-/*
- * Symbol table entries.
- */
-
-/* For accessing the fields of st_info. */
-
-/* For constructing st_info from field values. */
-
-/* For accessing the fields of st_other. */
-
-/*
- * Go linker interface
- */
-const (
-	ELF64HDRSIZE  = 64
-	ELF64PHDRSIZE = 56
-	ELF64SHDRSIZE = 64
-	ELF64RELSIZE  = 16
-	ELF64RELASIZE = 24
-	ELF64SYMSIZE  = 24
-	ELF32HDRSIZE  = 52
-	ELF32PHDRSIZE = 32
-	ELF32SHDRSIZE = 40
-	ELF32SYMSIZE  = 16
-	ELF32RELSIZE  = 8
-)
-
-/*
- * The interface uses the 64-bit structures always,
- * to avoid code duplication.  The writers know how to
- * marshal a 32-bit representation from the 64-bit structure.
- */
-
-var Elfstrdat []byte
-
-/*
- * Total amount of space to reserve at the start of the file
- * for Header, PHeaders, SHeaders, and interp.
- * May waste some.
- * On FreeBSD, cannot be larger than a page.
- */
-const (
-	ELFRESERVE = 4096
-)
-
-/*
- * We use the 64-bit data structures on both 32- and 64-bit machines
- * in order to write the code just once.  The 64-bit data structure is
- * written in the 32-bit format on the 32-bit machines.
- */
-const (
-	NSECT = 400
-)
-
-var (
-	Nelfsym = 1
-
-	elf64 bool
-	// Either ".rel" or ".rela" depending on which type of relocation the
-	// target platform uses.
-	elfRelType string
-
-	ehdr ElfEhdr
-	phdr [NSECT]*ElfPhdr
-	shdr [NSECT]*ElfShdr
-
-	interp string
-)
-
-type Elfstring struct {
-	s   string
-	off int
-}
-
-var elfstr [100]Elfstring
-
-var nelfstr int
-
-var buildinfo []byte
-
-/*
- Initialize the global variable that describes the ELF header. It will be updated as
- we write section and prog headers.
-*/
-func Elfinit(ctxt *Link) {
-	ctxt.IsELF = true
-
-	if ctxt.Arch.InFamily(sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) {
-		elfRelType = ".rela"
-	} else {
-		elfRelType = ".rel"
-	}
-
-	switch ctxt.Arch.Family {
-	// 64-bit architectures
-	case sys.PPC64, sys.S390X:
-		if ctxt.Arch.ByteOrder == binary.BigEndian {
-			ehdr.flags = 1 /* Version 1 ABI */
-		} else {
-			ehdr.flags = 2 /* Version 2 ABI */
-		}
-		fallthrough
-	case sys.AMD64, sys.ARM64, sys.MIPS64, sys.RISCV64:
-		if ctxt.Arch.Family == sys.MIPS64 {
-			ehdr.flags = 0x20000004 /* MIPS 3 CPIC */
-		}
-		elf64 = true
-
-		ehdr.phoff = ELF64HDRSIZE      /* Must be ELF64HDRSIZE: first PHdr must follow ELF header */
-		ehdr.shoff = ELF64HDRSIZE      /* Will move as we add PHeaders */
-		ehdr.ehsize = ELF64HDRSIZE     /* Must be ELF64HDRSIZE */
-		ehdr.phentsize = ELF64PHDRSIZE /* Must be ELF64PHDRSIZE */
-		ehdr.shentsize = ELF64SHDRSIZE /* Must be ELF64SHDRSIZE */
-
-	// 32-bit architectures
-	case sys.ARM, sys.MIPS:
-		if ctxt.Arch.Family == sys.ARM {
-			// we use EABI on linux/arm, freebsd/arm, netbsd/arm.
-			if ctxt.HeadType == objabi.Hlinux || ctxt.HeadType == objabi.Hfreebsd || ctxt.HeadType == objabi.Hnetbsd {
-				// We set a value here that makes no indication of which
-				// float ABI the object uses, because this is information
-				// used by the dynamic linker to compare executables and
-				// shared libraries -- so it only matters for cgo calls, and
-				// the information properly comes from the object files
-				// produced by the host C compiler. parseArmAttributes in
-				// ldelf.go reads that information and updates this field as
-				// appropriate.
-				ehdr.flags = 0x5000002 // has entry point, Version5 EABI
-			}
-		} else if ctxt.Arch.Family == sys.MIPS {
-			ehdr.flags = 0x50001004 /* MIPS 32 CPIC O32*/
-		}
-		fallthrough
-	default:
-		ehdr.phoff = ELF32HDRSIZE
-		/* Must be ELF32HDRSIZE: first PHdr must follow ELF header */
-		ehdr.shoff = ELF32HDRSIZE      /* Will move as we add PHeaders */
-		ehdr.ehsize = ELF32HDRSIZE     /* Must be ELF32HDRSIZE */
-		ehdr.phentsize = ELF32PHDRSIZE /* Must be ELF32PHDRSIZE */
-		ehdr.shentsize = ELF32SHDRSIZE /* Must be ELF32SHDRSIZE */
-	}
-}
-
-// Make sure PT_LOAD is aligned properly and
-// that there is no gap,
-// correct ELF loaders will do this implicitly,
-// but buggy ELF loaders like the one in some
-// versions of QEMU and UPX won't.
-func fixElfPhdr(e *ElfPhdr) {
-	frag := int(e.vaddr & (e.align - 1))
-
-	e.off -= uint64(frag)
-	e.vaddr -= uint64(frag)
-	e.paddr -= uint64(frag)
-	e.filesz += uint64(frag)
-	e.memsz += uint64(frag)
-}
-
-func elf64phdr(out *OutBuf, e *ElfPhdr) {
-	if e.type_ == PT_LOAD {
-		fixElfPhdr(e)
-	}
-
-	out.Write32(e.type_)
-	out.Write32(e.flags)
-	out.Write64(e.off)
-	out.Write64(e.vaddr)
-	out.Write64(e.paddr)
-	out.Write64(e.filesz)
-	out.Write64(e.memsz)
-	out.Write64(e.align)
-}
-
-func elf32phdr(out *OutBuf, e *ElfPhdr) {
-	if e.type_ == PT_LOAD {
-		fixElfPhdr(e)
-	}
-
-	out.Write32(e.type_)
-	out.Write32(uint32(e.off))
-	out.Write32(uint32(e.vaddr))
-	out.Write32(uint32(e.paddr))
-	out.Write32(uint32(e.filesz))
-	out.Write32(uint32(e.memsz))
-	out.Write32(e.flags)
-	out.Write32(uint32(e.align))
-}
-
-func elf64shdr(out *OutBuf, e *ElfShdr) {
-	out.Write32(e.name)
-	out.Write32(e.type_)
-	out.Write64(e.flags)
-	out.Write64(e.addr)
-	out.Write64(e.off)
-	out.Write64(e.size)
-	out.Write32(e.link)
-	out.Write32(e.info)
-	out.Write64(e.addralign)
-	out.Write64(e.entsize)
-}
-
-func elf32shdr(out *OutBuf, e *ElfShdr) {
-	out.Write32(e.name)
-	out.Write32(e.type_)
-	out.Write32(uint32(e.flags))
-	out.Write32(uint32(e.addr))
-	out.Write32(uint32(e.off))
-	out.Write32(uint32(e.size))
-	out.Write32(e.link)
-	out.Write32(e.info)
-	out.Write32(uint32(e.addralign))
-	out.Write32(uint32(e.entsize))
-}
-
-func elfwriteshdrs(out *OutBuf) uint32 {
-	if elf64 {
-		for i := 0; i < int(ehdr.shnum); i++ {
-			elf64shdr(out, shdr[i])
-		}
-		return uint32(ehdr.shnum) * ELF64SHDRSIZE
-	}
-
-	for i := 0; i < int(ehdr.shnum); i++ {
-		elf32shdr(out, shdr[i])
-	}
-	return uint32(ehdr.shnum) * ELF32SHDRSIZE
-}
-
-func elfsetstring(s *sym.Symbol, str string, off int) {
-	if nelfstr >= len(elfstr) {
-		Errorf(s, "too many elf strings")
-		errorexit()
-	}
-
-	elfstr[nelfstr].s = str
-	elfstr[nelfstr].off = off
-	nelfstr++
-}
-
-func elfwritephdrs(out *OutBuf) uint32 {
-	if elf64 {
-		for i := 0; i < int(ehdr.phnum); i++ {
-			elf64phdr(out, phdr[i])
-		}
-		return uint32(ehdr.phnum) * ELF64PHDRSIZE
-	}
-
-	for i := 0; i < int(ehdr.phnum); i++ {
-		elf32phdr(out, phdr[i])
-	}
-	return uint32(ehdr.phnum) * ELF32PHDRSIZE
-}
-
-func newElfPhdr() *ElfPhdr {
-	e := new(ElfPhdr)
-	if ehdr.phnum >= NSECT {
-		Errorf(nil, "too many phdrs")
-	} else {
-		phdr[ehdr.phnum] = e
-		ehdr.phnum++
-	}
-	if elf64 {
-		ehdr.shoff += ELF64PHDRSIZE
-	} else {
-		ehdr.shoff += ELF32PHDRSIZE
-	}
-	return e
-}
-
-func newElfShdr(name int64) *ElfShdr {
-	e := new(ElfShdr)
-	e.name = uint32(name)
-	e.shnum = int(ehdr.shnum)
-	if ehdr.shnum >= NSECT {
-		Errorf(nil, "too many shdrs")
-	} else {
-		shdr[ehdr.shnum] = e
-		ehdr.shnum++
-	}
-
-	return e
-}
-
-func getElfEhdr() *ElfEhdr {
-	return &ehdr
-}
-
-func elf64writehdr(out *OutBuf) uint32 {
-	out.Write(ehdr.ident[:])
-	out.Write16(ehdr.type_)
-	out.Write16(ehdr.machine)
-	out.Write32(ehdr.version)
-	out.Write64(ehdr.entry)
-	out.Write64(ehdr.phoff)
-	out.Write64(ehdr.shoff)
-	out.Write32(ehdr.flags)
-	out.Write16(ehdr.ehsize)
-	out.Write16(ehdr.phentsize)
-	out.Write16(ehdr.phnum)
-	out.Write16(ehdr.shentsize)
-	out.Write16(ehdr.shnum)
-	out.Write16(ehdr.shstrndx)
-	return ELF64HDRSIZE
-}
-
-func elf32writehdr(out *OutBuf) uint32 {
-	out.Write(ehdr.ident[:])
-	out.Write16(ehdr.type_)
-	out.Write16(ehdr.machine)
-	out.Write32(ehdr.version)
-	out.Write32(uint32(ehdr.entry))
-	out.Write32(uint32(ehdr.phoff))
-	out.Write32(uint32(ehdr.shoff))
-	out.Write32(ehdr.flags)
-	out.Write16(ehdr.ehsize)
-	out.Write16(ehdr.phentsize)
-	out.Write16(ehdr.phnum)
-	out.Write16(ehdr.shentsize)
-	out.Write16(ehdr.shnum)
-	out.Write16(ehdr.shstrndx)
-	return ELF32HDRSIZE
-}
-
-func elfwritehdr(out *OutBuf) uint32 {
-	if elf64 {
-		return elf64writehdr(out)
-	}
-	return elf32writehdr(out)
-}
-
-/* Taken directly from the definition document for ELF64 */
-func elfhash(name string) uint32 {
-	var h uint32
-	for i := 0; i < len(name); i++ {
-		h = (h << 4) + uint32(name[i])
-		if g := h & 0xf0000000; g != 0 {
-			h ^= g >> 24
-		}
-		h &= 0x0fffffff
-	}
-	return h
-}
-
-func Elfwritedynent(ctxt *Link, s *sym.Symbol, tag int, val uint64) {
-	if elf64 {
-		s.AddUint64(ctxt.Arch, uint64(tag))
-		s.AddUint64(ctxt.Arch, val)
-	} else {
-		s.AddUint32(ctxt.Arch, uint32(tag))
-		s.AddUint32(ctxt.Arch, uint32(val))
-	}
-}
-
-func elfwritedynentsym(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol) {
-	Elfwritedynentsymplus(ctxt, s, tag, t, 0)
-}
-
-func Elfwritedynentsymplus(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol, add int64) {
-	if elf64 {
-		s.AddUint64(ctxt.Arch, uint64(tag))
-	} else {
-		s.AddUint32(ctxt.Arch, uint32(tag))
-	}
-	s.AddAddrPlus(ctxt.Arch, t, add)
-}
-
-func elfwritedynentsymsize(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol) {
-	if elf64 {
-		s.AddUint64(ctxt.Arch, uint64(tag))
-	} else {
-		s.AddUint32(ctxt.Arch, uint32(tag))
-	}
-	s.AddSize(ctxt.Arch, t)
-}
-
-func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int {
-	interp = p
-	n := len(interp) + 1
-	sh.addr = startva + resoff - uint64(n)
-	sh.off = resoff - uint64(n)
-	sh.size = uint64(n)
-
-	return n
-}
-
-func elfwriteinterp(out *OutBuf) int {
-	sh := elfshname(".interp")
-	out.SeekSet(int64(sh.off))
-	out.WriteString(interp)
-	out.Write8(0)
-	return int(sh.size)
-}
-
-func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int) int {
-	n := 3*4 + uint64(sz) + resoff%4
-
-	sh.type_ = SHT_NOTE
-	sh.flags = SHF_ALLOC
-	sh.addralign = 4
-	sh.addr = startva + resoff - n
-	sh.off = resoff - n
-	sh.size = n - resoff%4
-
-	return int(n)
-}
-
-func elfwritenotehdr(out *OutBuf, str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr {
-	sh := elfshname(str)
-
-	// Write Elf_Note header.
-	out.SeekSet(int64(sh.off))
-
-	out.Write32(namesz)
-	out.Write32(descsz)
-	out.Write32(tag)
-
-	return sh
-}
-
-// NetBSD Signature (as per sys/exec_elf.h)
-const (
-	ELF_NOTE_NETBSD_NAMESZ  = 7
-	ELF_NOTE_NETBSD_DESCSZ  = 4
-	ELF_NOTE_NETBSD_TAG     = 1
-	ELF_NOTE_NETBSD_VERSION = 700000000 /* NetBSD 7.0 */
-)
-
-var ELF_NOTE_NETBSD_NAME = []byte("NetBSD\x00")
-
-func elfnetbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
-	n := int(Rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + Rnd(ELF_NOTE_NETBSD_DESCSZ, 4))
-	return elfnote(sh, startva, resoff, n)
-}
-
-func elfwritenetbsdsig(out *OutBuf) int {
-	// Write Elf_Note header.
-	sh := elfwritenotehdr(out, ".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG)
-
-	if sh == nil {
-		return 0
-	}
-
-	// Followed by NetBSD string and version.
-	out.Write(ELF_NOTE_NETBSD_NAME)
-	out.Write8(0)
-	out.Write32(ELF_NOTE_NETBSD_VERSION)
-
-	return int(sh.size)
-}
-
-// The race detector can't handle ASLR (address space layout randomization).
-// ASLR is on by default for NetBSD, so we turn the ASLR off eplicitly
-// using a magic elf Note when building race binaries.
-
-func elfnetbsdpax(sh *ElfShdr, startva uint64, resoff uint64) int {
-	n := int(Rnd(4, 4) + Rnd(4, 4))
-	return elfnote(sh, startva, resoff, n)
-}
-
-func elfwritenetbsdpax(out *OutBuf) int {
-	sh := elfwritenotehdr(out, ".note.netbsd.pax", 4 /* length of PaX\x00 */, 4 /* length of flags */, 0x03 /* PaX type */)
-	if sh == nil {
-		return 0
-	}
-	out.Write([]byte("PaX\x00"))
-	out.Write32(0x20) // 0x20 = Force disable ASLR
-	return int(sh.size)
-}
-
-// OpenBSD Signature
-const (
-	ELF_NOTE_OPENBSD_NAMESZ  = 8
-	ELF_NOTE_OPENBSD_DESCSZ  = 4
-	ELF_NOTE_OPENBSD_TAG     = 1
-	ELF_NOTE_OPENBSD_VERSION = 0
-)
-
-var ELF_NOTE_OPENBSD_NAME = []byte("OpenBSD\x00")
-
-func elfopenbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
-	n := ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ
-	return elfnote(sh, startva, resoff, n)
-}
-
-func elfwriteopenbsdsig(out *OutBuf) int {
-	// Write Elf_Note header.
-	sh := elfwritenotehdr(out, ".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG)
-
-	if sh == nil {
-		return 0
-	}
-
-	// Followed by OpenBSD string and version.
-	out.Write(ELF_NOTE_OPENBSD_NAME)
-
-	out.Write32(ELF_NOTE_OPENBSD_VERSION)
-
-	return int(sh.size)
-}
-
-func addbuildinfo(val string) {
-	if !strings.HasPrefix(val, "0x") {
-		Exitf("-B argument must start with 0x: %s", val)
-	}
-
-	ov := val
-	val = val[2:]
-
-	const maxLen = 32
-	if hex.DecodedLen(len(val)) > maxLen {
-		Exitf("-B option too long (max %d digits): %s", maxLen, ov)
-	}
-
-	b, err := hex.DecodeString(val)
-	if err != nil {
-		if err == hex.ErrLength {
-			Exitf("-B argument must have even number of digits: %s", ov)
-		}
-		if inv, ok := err.(hex.InvalidByteError); ok {
-			Exitf("-B argument contains invalid hex digit %c: %s", byte(inv), ov)
-		}
-		Exitf("-B argument contains invalid hex: %s", ov)
-	}
-
-	buildinfo = b
-}
-
-// Build info note
-const (
-	ELF_NOTE_BUILDINFO_NAMESZ = 4
-	ELF_NOTE_BUILDINFO_TAG    = 3
-)
-
-var ELF_NOTE_BUILDINFO_NAME = []byte("GNU\x00")
-
-func elfbuildinfo(sh *ElfShdr, startva uint64, resoff uint64) int {
-	n := int(ELF_NOTE_BUILDINFO_NAMESZ + Rnd(int64(len(buildinfo)), 4))
-	return elfnote(sh, startva, resoff, n)
-}
-
-func elfgobuildid(sh *ElfShdr, startva uint64, resoff uint64) int {
-	n := len(ELF_NOTE_GO_NAME) + int(Rnd(int64(len(*flagBuildid)), 4))
-	return elfnote(sh, startva, resoff, n)
-}
-
-func elfwritebuildinfo(out *OutBuf) int {
-	sh := elfwritenotehdr(out, ".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG)
-	if sh == nil {
-		return 0
-	}
-
-	out.Write(ELF_NOTE_BUILDINFO_NAME)
-	out.Write(buildinfo)
-	var zero = make([]byte, 4)
-	out.Write(zero[:int(Rnd(int64(len(buildinfo)), 4)-int64(len(buildinfo)))])
-
-	return int(sh.size)
-}
-
-func elfwritegobuildid(out *OutBuf) int {
-	sh := elfwritenotehdr(out, ".note.go.buildid", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(*flagBuildid)), ELF_NOTE_GOBUILDID_TAG)
-	if sh == nil {
-		return 0
-	}
-
-	out.Write(ELF_NOTE_GO_NAME)
-	out.Write([]byte(*flagBuildid))
-	var zero = make([]byte, 4)
-	out.Write(zero[:int(Rnd(int64(len(*flagBuildid)), 4)-int64(len(*flagBuildid)))])
-
-	return int(sh.size)
-}
-
-// Go specific notes
-const (
-	ELF_NOTE_GOPKGLIST_TAG = 1
-	ELF_NOTE_GOABIHASH_TAG = 2
-	ELF_NOTE_GODEPS_TAG    = 3
-	ELF_NOTE_GOBUILDID_TAG = 4
-)
-
-var ELF_NOTE_GO_NAME = []byte("Go\x00\x00")
-
-var elfverneed int
-
-type Elfaux struct {
-	next *Elfaux
-	num  int
-	vers string
-}
-
-type Elflib struct {
-	next *Elflib
-	aux  *Elfaux
-	file string
-}
-
-func addelflib(list **Elflib, file string, vers string) *Elfaux {
-	var lib *Elflib
-
-	for lib = *list; lib != nil; lib = lib.next {
-		if lib.file == file {
-			goto havelib
-		}
-	}
-	lib = new(Elflib)
-	lib.next = *list
-	lib.file = file
-	*list = lib
-
-havelib:
-	for aux := lib.aux; aux != nil; aux = aux.next {
-		if aux.vers == vers {
-			return aux
-		}
-	}
-	aux := new(Elfaux)
-	aux.next = lib.aux
-	aux.vers = vers
-	lib.aux = aux
-
-	return aux
-}
-
-func elfdynhash(ctxt *Link) {
-	if !ctxt.IsELF {
-		return
-	}
-
-	nsym := Nelfsym
-	s := ctxt.Syms.Lookup(".hash", 0)
-	s.Type = sym.SELFROSECT
-	s.Attr |= sym.AttrReachable
-
-	i := nsym
-	nbucket := 1
-	for i > 0 {
-		nbucket++
-		i >>= 1
-	}
-
-	var needlib *Elflib
-	need := make([]*Elfaux, nsym)
-	chain := make([]uint32, nsym)
-	buckets := make([]uint32, nbucket)
-
-	for _, sy := range ctxt.Syms.Allsym {
-		if sy.Dynid <= 0 {
-			continue
-		}
-
-		if sy.Dynimpvers() != "" {
-			need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib(), sy.Dynimpvers())
-		}
-
-		name := sy.Extname()
-		hc := elfhash(name)
-
-		b := hc % uint32(nbucket)
-		chain[sy.Dynid] = buckets[b]
-		buckets[b] = uint32(sy.Dynid)
-	}
-
-	// s390x (ELF64) hash table entries are 8 bytes
-	if ctxt.Arch.Family == sys.S390X {
-		s.AddUint64(ctxt.Arch, uint64(nbucket))
-		s.AddUint64(ctxt.Arch, uint64(nsym))
-		for i := 0; i < nbucket; i++ {
-			s.AddUint64(ctxt.Arch, uint64(buckets[i]))
-		}
-		for i := 0; i < nsym; i++ {
-			s.AddUint64(ctxt.Arch, uint64(chain[i]))
-		}
-	} else {
-		s.AddUint32(ctxt.Arch, uint32(nbucket))
-		s.AddUint32(ctxt.Arch, uint32(nsym))
-		for i := 0; i < nbucket; i++ {
-			s.AddUint32(ctxt.Arch, buckets[i])
-		}
-		for i := 0; i < nsym; i++ {
-			s.AddUint32(ctxt.Arch, chain[i])
-		}
-	}
-
-	// version symbols
-	dynstr := ctxt.Syms.Lookup(".dynstr", 0)
-
-	s = ctxt.Syms.Lookup(".gnu.version_r", 0)
-	i = 2
-	nfile := 0
-	for l := needlib; l != nil; l = l.next {
-		nfile++
-
-		// header
-		s.AddUint16(ctxt.Arch, 1) // table version
-		j := 0
-		for x := l.aux; x != nil; x = x.next {
-			j++
-		}
-		s.AddUint16(ctxt.Arch, uint16(j))                         // aux count
-		s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, l.file))) // file string offset
-		s.AddUint32(ctxt.Arch, 16)                                // offset from header to first aux
-		if l.next != nil {
-			s.AddUint32(ctxt.Arch, 16+uint32(j)*16) // offset from this header to next
-		} else {
-			s.AddUint32(ctxt.Arch, 0)
-		}
-
-		for x := l.aux; x != nil; x = x.next {
-			x.num = i
-			i++
-
-			// aux struct
-			s.AddUint32(ctxt.Arch, elfhash(x.vers))                   // hash
-			s.AddUint16(ctxt.Arch, 0)                                 // flags
-			s.AddUint16(ctxt.Arch, uint16(x.num))                     // other - index we refer to this by
-			s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, x.vers))) // version string offset
-			if x.next != nil {
-				s.AddUint32(ctxt.Arch, 16) // offset from this aux to next
-			} else {
-				s.AddUint32(ctxt.Arch, 0)
-			}
-		}
-	}
-
-	// version references
-	s = ctxt.Syms.Lookup(".gnu.version", 0)
-
-	for i := 0; i < nsym; i++ {
-		if i == 0 {
-			s.AddUint16(ctxt.Arch, 0) // first entry - no symbol
-		} else if need[i] == nil {
-			s.AddUint16(ctxt.Arch, 1) // global
-		} else {
-			s.AddUint16(ctxt.Arch, uint16(need[i].num))
-		}
-	}
-
-	s = ctxt.Syms.Lookup(".dynamic", 0)
-	elfverneed = nfile
-	if elfverneed != 0 {
-		elfwritedynentsym(ctxt, s, DT_VERNEED, ctxt.Syms.Lookup(".gnu.version_r", 0))
-		Elfwritedynent(ctxt, s, DT_VERNEEDNUM, uint64(nfile))
-		elfwritedynentsym(ctxt, s, DT_VERSYM, ctxt.Syms.Lookup(".gnu.version", 0))
-	}
-
-	sy := ctxt.Syms.Lookup(elfRelType+".plt", 0)
-	if sy.Size > 0 {
-		if elfRelType == ".rela" {
-			Elfwritedynent(ctxt, s, DT_PLTREL, DT_RELA)
-		} else {
-			Elfwritedynent(ctxt, s, DT_PLTREL, DT_REL)
-		}
-		elfwritedynentsymsize(ctxt, s, DT_PLTRELSZ, sy)
-		elfwritedynentsym(ctxt, s, DT_JMPREL, sy)
-	}
-
-	Elfwritedynent(ctxt, s, DT_NULL, 0)
-}
-
-func elfphload(seg *sym.Segment) *ElfPhdr {
-	ph := newElfPhdr()
-	ph.type_ = PT_LOAD
-	if seg.Rwx&4 != 0 {
-		ph.flags |= PF_R
-	}
-	if seg.Rwx&2 != 0 {
-		ph.flags |= PF_W
-	}
-	if seg.Rwx&1 != 0 {
-		ph.flags |= PF_X
-	}
-	ph.vaddr = seg.Vaddr
-	ph.paddr = seg.Vaddr
-	ph.memsz = seg.Length
-	ph.off = seg.Fileoff
-	ph.filesz = seg.Filelen
-	ph.align = uint64(*FlagRound)
-
-	return ph
-}
-
-func elfphrelro(seg *sym.Segment) {
-	ph := newElfPhdr()
-	ph.type_ = PT_GNU_RELRO
-	ph.vaddr = seg.Vaddr
-	ph.paddr = seg.Vaddr
-	ph.memsz = seg.Length
-	ph.off = seg.Fileoff
-	ph.filesz = seg.Filelen
-	ph.align = uint64(*FlagRound)
-}
-
-func elfshname(name string) *ElfShdr {
-	for i := 0; i < nelfstr; i++ {
-		if name != elfstr[i].s {
-			continue
-		}
-		off := elfstr[i].off
-		for i = 0; i < int(ehdr.shnum); i++ {
-			sh := shdr[i]
-			if sh.name == uint32(off) {
-				return sh
-			}
-		}
-		return newElfShdr(int64(off))
-	}
-	Exitf("cannot find elf name %s", name)
-	return nil
-}
-
-// Create an ElfShdr for the section with name.
-// Create a duplicate if one already exists with that name
-func elfshnamedup(name string) *ElfShdr {
-	for i := 0; i < nelfstr; i++ {
-		if name == elfstr[i].s {
-			off := elfstr[i].off
-			return newElfShdr(int64(off))
-		}
-	}
-
-	Errorf(nil, "cannot find elf name %s", name)
-	errorexit()
-	return nil
-}
-
-func elfshalloc(sect *sym.Section) *ElfShdr {
-	sh := elfshname(sect.Name)
-	sect.Elfsect = sh
-	return sh
-}
-
-func elfshbits(linkmode LinkMode, sect *sym.Section) *ElfShdr {
-	var sh *ElfShdr
-
-	if sect.Name == ".text" {
-		if sect.Elfsect == nil {
-			sect.Elfsect = elfshnamedup(sect.Name)
-		}
-		sh = sect.Elfsect.(*ElfShdr)
-	} else {
-		sh = elfshalloc(sect)
-	}
-
-	// If this section has already been set up as a note, we assume type_ and
-	// flags are already correct, but the other fields still need filling in.
-	if sh.type_ == SHT_NOTE {
-		if linkmode != LinkExternal {
-			// TODO(mwhudson): the approach here will work OK when
-			// linking internally for notes that we want to be included
-			// in a loadable segment (e.g. the abihash note) but not for
-			// notes that we do not want to be mapped (e.g. the package
-			// list note). The real fix is probably to define new values
-			// for Symbol.Type corresponding to mapped and unmapped notes
-			// and handle them in dodata().
-			Errorf(nil, "sh.type_ == SHT_NOTE in elfshbits when linking internally")
-		}
-		sh.addralign = uint64(sect.Align)
-		sh.size = sect.Length
-		sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
-		return sh
-	}
-	if sh.type_ > 0 {
-		return sh
-	}
-
-	if sect.Vaddr < sect.Seg.Vaddr+sect.Seg.Filelen {
-		sh.type_ = SHT_PROGBITS
-	} else {
-		sh.type_ = SHT_NOBITS
-	}
-	sh.flags = SHF_ALLOC
-	if sect.Rwx&1 != 0 {
-		sh.flags |= SHF_EXECINSTR
-	}
-	if sect.Rwx&2 != 0 {
-		sh.flags |= SHF_WRITE
-	}
-	if sect.Name == ".tbss" {
-		sh.flags |= SHF_TLS
-		sh.type_ = SHT_NOBITS
-	}
-	if strings.HasPrefix(sect.Name, ".debug") || strings.HasPrefix(sect.Name, ".zdebug") {
-		sh.flags = 0
-	}
-
-	if linkmode != LinkExternal {
-		sh.addr = sect.Vaddr
-	}
-	sh.addralign = uint64(sect.Align)
-	sh.size = sect.Length
-	if sect.Name != ".tbss" {
-		sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
-	}
-
-	return sh
-}
-
-func elfshreloc(arch *sys.Arch, sect *sym.Section) *ElfShdr {
-	// If main section is SHT_NOBITS, nothing to relocate.
-	// Also nothing to relocate in .shstrtab or notes.
-	if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
-		return nil
-	}
-	if sect.Name == ".shstrtab" || sect.Name == ".tbss" {
-		return nil
-	}
-	if sect.Elfsect.(*ElfShdr).type_ == SHT_NOTE {
-		return nil
-	}
-
-	typ := SHT_REL
-	if elfRelType == ".rela" {
-		typ = SHT_RELA
-	}
-
-	sh := elfshname(elfRelType + sect.Name)
-	// There could be multiple text sections but each needs
-	// its own .rela.text.
-
-	if sect.Name == ".text" {
-		if sh.info != 0 && sh.info != uint32(sect.Elfsect.(*ElfShdr).shnum) {
-			sh = elfshnamedup(elfRelType + sect.Name)
-		}
-	}
-
-	sh.type_ = uint32(typ)
-	sh.entsize = uint64(arch.RegSize) * 2
-	if typ == SHT_RELA {
-		sh.entsize += uint64(arch.RegSize)
-	}
-	sh.link = uint32(elfshname(".symtab").shnum)
-	sh.info = uint32(sect.Elfsect.(*ElfShdr).shnum)
-	sh.off = sect.Reloff
-	sh.size = sect.Rellen
-	sh.addralign = uint64(arch.RegSize)
-	return sh
-}
-
-func elfrelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) {
-	// If main section is SHT_NOBITS, nothing to relocate.
-	// Also nothing to relocate in .shstrtab.
-	if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
-		return
-	}
-	if sect.Name == ".shstrtab" {
-		return
-	}
-
-	sect.Reloff = uint64(ctxt.Out.Offset())
-	for i, s := range syms {
-		if !s.Attr.Reachable() {
-			continue
-		}
-		if uint64(s.Value) >= sect.Vaddr {
-			syms = syms[i:]
-			break
-		}
-	}
-
-	eaddr := int32(sect.Vaddr + sect.Length)
-	for _, s := range syms {
-		if !s.Attr.Reachable() {
-			continue
-		}
-		if s.Value >= int64(eaddr) {
-			break
-		}
-		for ri := range s.R {
-			r := &s.R[ri]
-			if r.Done {
-				continue
-			}
-			if r.Xsym == nil {
-				Errorf(s, "missing xsym in relocation %#v %#v", r.Sym.Name, s)
-				continue
-			}
-			if r.Xsym.ElfsymForReloc() == 0 {
-				Errorf(s, "reloc %d (%s) to non-elf symbol %s (outer=%s) %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Sym.Name, r.Xsym.Name, r.Sym.Type, r.Sym.Type)
-			}
-			if !r.Xsym.Attr.Reachable() {
-				Errorf(s, "unreachable reloc %d (%s) target %v", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Xsym.Name)
-			}
-			if !thearch.Elfreloc1(ctxt, r, int64(uint64(s.Value+int64(r.Off))-sect.Vaddr)) {
-				Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name)
-			}
-		}
-	}
-
-	sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
-}
-
-func Elfemitreloc(ctxt *Link) {
-	for ctxt.Out.Offset()&7 != 0 {
-		ctxt.Out.Write8(0)
-	}
-
-	for _, sect := range Segtext.Sections {
-		if sect.Name == ".text" {
-			elfrelocsect(ctxt, sect, ctxt.Textp)
-		} else {
-			elfrelocsect(ctxt, sect, datap)
-		}
-	}
-
-	for _, sect := range Segrodata.Sections {
-		elfrelocsect(ctxt, sect, datap)
-	}
-	for _, sect := range Segrelrodata.Sections {
-		elfrelocsect(ctxt, sect, datap)
-	}
-	for _, sect := range Segdata.Sections {
-		elfrelocsect(ctxt, sect, datap)
-	}
-	for _, sect := range Segdwarf.Sections {
-		elfrelocsect(ctxt, sect, dwarfp)
-	}
-}
-
-func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) {
-	s := ctxt.Syms.Lookup(sectionName, 0)
-	s.Attr |= sym.AttrReachable
-	s.Type = sym.SELFROSECT
-	// namesz
-	s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME)))
-	// descsz
-	s.AddUint32(ctxt.Arch, uint32(len(desc)))
-	// tag
-	s.AddUint32(ctxt.Arch, tag)
-	// name + padding
-	s.P = append(s.P, ELF_NOTE_GO_NAME...)
-	for len(s.P)%4 != 0 {
-		s.P = append(s.P, 0)
-	}
-	// desc + padding
-	s.P = append(s.P, desc...)
-	for len(s.P)%4 != 0 {
-		s.P = append(s.P, 0)
-	}
-	s.Size = int64(len(s.P))
-	s.Align = 4
-}
-
-func (ctxt *Link) doelf() {
-	if !ctxt.IsELF {
-		return
-	}
-
-	/* predefine strings we need for section headers */
-	shstrtab := ctxt.Syms.Lookup(".shstrtab", 0)
-
-	shstrtab.Type = sym.SELFROSECT
-	shstrtab.Attr |= sym.AttrReachable
-
-	Addstring(shstrtab, "")
-	Addstring(shstrtab, ".text")
-	Addstring(shstrtab, ".noptrdata")
-	Addstring(shstrtab, ".data")
-	Addstring(shstrtab, ".bss")
-	Addstring(shstrtab, ".noptrbss")
-	Addstring(shstrtab, "__libfuzzer_extra_counters")
-	Addstring(shstrtab, ".go.buildinfo")
-
-	// generate .tbss section for dynamic internal linker or external
-	// linking, so that various binutils could correctly calculate
-	// PT_TLS size. See https://golang.org/issue/5200.
-	if !*FlagD || ctxt.LinkMode == LinkExternal {
-		Addstring(shstrtab, ".tbss")
-	}
-	if ctxt.HeadType == objabi.Hnetbsd {
-		Addstring(shstrtab, ".note.netbsd.ident")
-		if *flagRace {
-			Addstring(shstrtab, ".note.netbsd.pax")
-		}
-	}
-	if ctxt.HeadType == objabi.Hopenbsd {
-		Addstring(shstrtab, ".note.openbsd.ident")
-	}
-	if len(buildinfo) > 0 {
-		Addstring(shstrtab, ".note.gnu.build-id")
-	}
-	if *flagBuildid != "" {
-		Addstring(shstrtab, ".note.go.buildid")
-	}
-	Addstring(shstrtab, ".elfdata")
-	Addstring(shstrtab, ".rodata")
-	// See the comment about data.rel.ro.FOO section names in data.go.
-	relro_prefix := ""
-	if ctxt.UseRelro() {
-		Addstring(shstrtab, ".data.rel.ro")
-		relro_prefix = ".data.rel.ro"
-	}
-	Addstring(shstrtab, relro_prefix+".typelink")
-	Addstring(shstrtab, relro_prefix+".itablink")
-	Addstring(shstrtab, relro_prefix+".gosymtab")
-	Addstring(shstrtab, relro_prefix+".gopclntab")
-
-	if ctxt.LinkMode == LinkExternal {
-		*FlagD = true
-
-		Addstring(shstrtab, elfRelType+".text")
-		Addstring(shstrtab, elfRelType+".rodata")
-		Addstring(shstrtab, elfRelType+relro_prefix+".typelink")
-		Addstring(shstrtab, elfRelType+relro_prefix+".itablink")
-		Addstring(shstrtab, elfRelType+relro_prefix+".gosymtab")
-		Addstring(shstrtab, elfRelType+relro_prefix+".gopclntab")
-		Addstring(shstrtab, elfRelType+".noptrdata")
-		Addstring(shstrtab, elfRelType+".data")
-		if ctxt.UseRelro() {
-			Addstring(shstrtab, elfRelType+".data.rel.ro")
-		}
-		Addstring(shstrtab, elfRelType+".go.buildinfo")
-
-		// add a .note.GNU-stack section to mark the stack as non-executable
-		Addstring(shstrtab, ".note.GNU-stack")
-
-		if ctxt.BuildMode == BuildModeShared {
-			Addstring(shstrtab, ".note.go.abihash")
-			Addstring(shstrtab, ".note.go.pkg-list")
-			Addstring(shstrtab, ".note.go.deps")
-		}
-	}
-
-	hasinitarr := ctxt.linkShared
-
-	/* shared library initializer */
-	switch ctxt.BuildMode {
-	case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin:
-		hasinitarr = true
-	}
-
-	if hasinitarr {
-		Addstring(shstrtab, ".init_array")
-		Addstring(shstrtab, elfRelType+".init_array")
-	}
-
-	if !*FlagS {
-		Addstring(shstrtab, ".symtab")
-		Addstring(shstrtab, ".strtab")
-		dwarfaddshstrings(ctxt, shstrtab)
-	}
-
-	Addstring(shstrtab, ".shstrtab")
-
-	if !*FlagD { /* -d suppresses dynamic loader format */
-		Addstring(shstrtab, ".interp")
-		Addstring(shstrtab, ".hash")
-		Addstring(shstrtab, ".got")
-		if ctxt.Arch.Family == sys.PPC64 {
-			Addstring(shstrtab, ".glink")
-		}
-		Addstring(shstrtab, ".got.plt")
-		Addstring(shstrtab, ".dynamic")
-		Addstring(shstrtab, ".dynsym")
-		Addstring(shstrtab, ".dynstr")
-		Addstring(shstrtab, elfRelType)
-		Addstring(shstrtab, elfRelType+".plt")
-
-		Addstring(shstrtab, ".plt")
-		Addstring(shstrtab, ".gnu.version")
-		Addstring(shstrtab, ".gnu.version_r")
-
-		/* dynamic symbol table - first entry all zeros */
-		s := ctxt.Syms.Lookup(".dynsym", 0)
-
-		s.Type = sym.SELFROSECT
-		s.Attr |= sym.AttrReachable
-		if elf64 {
-			s.Size += ELF64SYMSIZE
-		} else {
-			s.Size += ELF32SYMSIZE
-		}
-
-		/* dynamic string table */
-		s = ctxt.Syms.Lookup(".dynstr", 0)
-
-		s.Type = sym.SELFROSECT
-		s.Attr |= sym.AttrReachable
-		if s.Size == 0 {
-			Addstring(s, "")
-		}
-		dynstr := s
-
-		/* relocation table */
-		s = ctxt.Syms.Lookup(elfRelType, 0)
-		s.Attr |= sym.AttrReachable
-		s.Type = sym.SELFROSECT
-
-		/* global offset table */
-		s = ctxt.Syms.Lookup(".got", 0)
-
-		s.Attr |= sym.AttrReachable
-		s.Type = sym.SELFGOT // writable
-
-		/* ppc64 glink resolver */
-		if ctxt.Arch.Family == sys.PPC64 {
-			s := ctxt.Syms.Lookup(".glink", 0)
-			s.Attr |= sym.AttrReachable
-			s.Type = sym.SELFRXSECT
-		}
-
-		/* hash */
-		s = ctxt.Syms.Lookup(".hash", 0)
-
-		s.Attr |= sym.AttrReachable
-		s.Type = sym.SELFROSECT
-
-		s = ctxt.Syms.Lookup(".got.plt", 0)
-		s.Attr |= sym.AttrReachable
-		s.Type = sym.SELFSECT // writable
-
-		s = ctxt.Syms.Lookup(".plt", 0)
-
-		s.Attr |= sym.AttrReachable
-		if ctxt.Arch.Family == sys.PPC64 {
-			// In the ppc64 ABI, .plt is a data section
-			// written by the dynamic linker.
-			s.Type = sym.SELFSECT
-		} else {
-			s.Type = sym.SELFRXSECT
-		}
-
-		thearch.Elfsetupplt(ctxt)
-
-		s = ctxt.Syms.Lookup(elfRelType+".plt", 0)
-		s.Attr |= sym.AttrReachable
-		s.Type = sym.SELFROSECT
-
-		s = ctxt.Syms.Lookup(".gnu.version", 0)
-		s.Attr |= sym.AttrReachable
-		s.Type = sym.SELFROSECT
-
-		s = ctxt.Syms.Lookup(".gnu.version_r", 0)
-		s.Attr |= sym.AttrReachable
-		s.Type = sym.SELFROSECT
-
-		/* define dynamic elf table */
-		s = ctxt.Syms.Lookup(".dynamic", 0)
-
-		s.Attr |= sym.AttrReachable
-		s.Type = sym.SELFSECT // writable
-
-		/*
-		 * .dynamic table
-		 */
-		elfwritedynentsym(ctxt, s, DT_HASH, ctxt.Syms.Lookup(".hash", 0))
-
-		elfwritedynentsym(ctxt, s, DT_SYMTAB, ctxt.Syms.Lookup(".dynsym", 0))
-		if elf64 {
-			Elfwritedynent(ctxt, s, DT_SYMENT, ELF64SYMSIZE)
-		} else {
-			Elfwritedynent(ctxt, s, DT_SYMENT, ELF32SYMSIZE)
-		}
-		elfwritedynentsym(ctxt, s, DT_STRTAB, ctxt.Syms.Lookup(".dynstr", 0))
-		elfwritedynentsymsize(ctxt, s, DT_STRSZ, ctxt.Syms.Lookup(".dynstr", 0))
-		if elfRelType == ".rela" {
-			elfwritedynentsym(ctxt, s, DT_RELA, ctxt.Syms.Lookup(".rela", 0))
-			elfwritedynentsymsize(ctxt, s, DT_RELASZ, ctxt.Syms.Lookup(".rela", 0))
-			Elfwritedynent(ctxt, s, DT_RELAENT, ELF64RELASIZE)
-		} else {
-			elfwritedynentsym(ctxt, s, DT_REL, ctxt.Syms.Lookup(".rel", 0))
-			elfwritedynentsymsize(ctxt, s, DT_RELSZ, ctxt.Syms.Lookup(".rel", 0))
-			Elfwritedynent(ctxt, s, DT_RELENT, ELF32RELSIZE)
-		}
-
-		if rpath.val != "" {
-			Elfwritedynent(ctxt, s, DT_RUNPATH, uint64(Addstring(dynstr, rpath.val)))
-		}
-
-		if ctxt.Arch.Family == sys.PPC64 {
-			elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".plt", 0))
-		} else if ctxt.Arch.Family == sys.S390X {
-			elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".got", 0))
-		} else {
-			elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".got.plt", 0))
-		}
-
-		if ctxt.Arch.Family == sys.PPC64 {
-			Elfwritedynent(ctxt, s, DT_PPC64_OPT, 0)
-		}
-
-		// Solaris dynamic linker can't handle an empty .rela.plt if
-		// DT_JMPREL is emitted so we have to defer generation of DT_PLTREL,
-		// DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the
-		// size of .rel(a).plt section.
-		Elfwritedynent(ctxt, s, DT_DEBUG, 0)
-	}
-
-	if ctxt.BuildMode == BuildModeShared {
-		// The go.link.abihashbytes symbol will be pointed at the appropriate
-		// part of the .note.go.abihash section in data.go:func address().
-		s := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
-		s.Attr |= sym.AttrLocal
-		s.Type = sym.SRODATA
-		s.Attr |= sym.AttrSpecial
-		s.Attr |= sym.AttrReachable
-		s.Size = int64(sha1.Size)
-
-		sort.Sort(byPkg(ctxt.Library))
-		h := sha1.New()
-		for _, l := range ctxt.Library {
-			io.WriteString(h, l.Hash)
-		}
-		addgonote(ctxt, ".note.go.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{}))
-		addgonote(ctxt, ".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote)
-		var deplist []string
-		for _, shlib := range ctxt.Shlibs {
-			deplist = append(deplist, filepath.Base(shlib.Path))
-		}
-		addgonote(ctxt, ".note.go.deps", ELF_NOTE_GODEPS_TAG, []byte(strings.Join(deplist, "\n")))
-	}
-
-	if ctxt.LinkMode == LinkExternal && *flagBuildid != "" {
-		addgonote(ctxt, ".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(*flagBuildid))
-	}
-}
-
-// Do not write DT_NULL.  elfdynhash will finish it.
-func shsym(sh *ElfShdr, s *sym.Symbol) {
-	addr := Symaddr(s)
-	if sh.flags&SHF_ALLOC != 0 {
-		sh.addr = uint64(addr)
-	}
-	sh.off = uint64(datoff(s, addr))
-	sh.size = uint64(s.Size)
-}
-
-func phsh(ph *ElfPhdr, sh *ElfShdr) {
-	ph.vaddr = sh.addr
-	ph.paddr = ph.vaddr
-	ph.off = sh.off
-	ph.filesz = sh.size
-	ph.memsz = sh.size
-	ph.align = sh.addralign
-}
-
-func Asmbelfsetup() {
-	/* This null SHdr must appear before all others */
-	elfshname("")
-
-	for _, sect := range Segtext.Sections {
-		// There could be multiple .text sections. Instead check the Elfsect
-		// field to determine if already has an ElfShdr and if not, create one.
-		if sect.Name == ".text" {
-			if sect.Elfsect == nil {
-				sect.Elfsect = elfshnamedup(sect.Name)
-			}
-		} else {
-			elfshalloc(sect)
-		}
-	}
-	for _, sect := range Segrodata.Sections {
-		elfshalloc(sect)
-	}
-	for _, sect := range Segrelrodata.Sections {
-		elfshalloc(sect)
-	}
-	for _, sect := range Segdata.Sections {
-		elfshalloc(sect)
-	}
-	for _, sect := range Segdwarf.Sections {
-		elfshalloc(sect)
-	}
-}
-
-func Asmbelf(ctxt *Link, symo int64) {
-	eh := getElfEhdr()
-	switch ctxt.Arch.Family {
-	default:
-		Exitf("unknown architecture in asmbelf: %v", ctxt.Arch.Family)
-	case sys.MIPS, sys.MIPS64:
-		eh.machine = EM_MIPS
-	case sys.ARM:
-		eh.machine = EM_ARM
-	case sys.AMD64:
-		eh.machine = EM_X86_64
-	case sys.ARM64:
-		eh.machine = EM_AARCH64
-	case sys.I386:
-		eh.machine = EM_386
-	case sys.PPC64:
-		eh.machine = EM_PPC64
-	case sys.RISCV64:
-		eh.machine = EM_RISCV
-	case sys.S390X:
-		eh.machine = EM_S390
-	}
-
-	elfreserve := int64(ELFRESERVE)
-
-	numtext := int64(0)
-	for _, sect := range Segtext.Sections {
-		if sect.Name == ".text" {
-			numtext++
-		}
-	}
-
-	// If there are multiple text sections, extra space is needed
-	// in the elfreserve for the additional .text and .rela.text
-	// section headers.  It can handle 4 extra now. Headers are
-	// 64 bytes.
-
-	if numtext > 4 {
-		elfreserve += elfreserve + numtext*64*2
-	}
-
-	startva := *FlagTextAddr - int64(HEADR)
-	resoff := elfreserve
-
-	var pph *ElfPhdr
-	var pnote *ElfPhdr
-	if *flagRace && ctxt.HeadType == objabi.Hnetbsd {
-		sh := elfshname(".note.netbsd.pax")
-		resoff -= int64(elfnetbsdpax(sh, uint64(startva), uint64(resoff)))
-		pnote = newElfPhdr()
-		pnote.type_ = PT_NOTE
-		pnote.flags = PF_R
-		phsh(pnote, sh)
-	}
-	if ctxt.LinkMode == LinkExternal {
-		/* skip program headers */
-		eh.phoff = 0
-
-		eh.phentsize = 0
-
-		if ctxt.BuildMode == BuildModeShared {
-			sh := elfshname(".note.go.pkg-list")
-			sh.type_ = SHT_NOTE
-			sh = elfshname(".note.go.abihash")
-			sh.type_ = SHT_NOTE
-			sh.flags = SHF_ALLOC
-			sh = elfshname(".note.go.deps")
-			sh.type_ = SHT_NOTE
-		}
-
-		if *flagBuildid != "" {
-			sh := elfshname(".note.go.buildid")
-			sh.type_ = SHT_NOTE
-			sh.flags = SHF_ALLOC
-		}
-
-		goto elfobj
-	}
-
-	/* program header info */
-	pph = newElfPhdr()
-
-	pph.type_ = PT_PHDR
-	pph.flags = PF_R
-	pph.off = uint64(eh.ehsize)
-	pph.vaddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off
-	pph.paddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off
-	pph.align = uint64(*FlagRound)
-
-	/*
-	 * PHDR must be in a loaded segment. Adjust the text
-	 * segment boundaries downwards to include it.
-	 */
-	{
-		o := int64(Segtext.Vaddr - pph.vaddr)
-		Segtext.Vaddr -= uint64(o)
-		Segtext.Length += uint64(o)
-		o = int64(Segtext.Fileoff - pph.off)
-		Segtext.Fileoff -= uint64(o)
-		Segtext.Filelen += uint64(o)
-	}
-
-	if !*FlagD { /* -d suppresses dynamic loader format */
-		/* interpreter */
-		sh := elfshname(".interp")
-
-		sh.type_ = SHT_PROGBITS
-		sh.flags = SHF_ALLOC
-		sh.addralign = 1
-
-		if interpreter == "" && objabi.GO_LDSO != "" {
-			interpreter = objabi.GO_LDSO
-		}
-
-		if interpreter == "" {
-			switch ctxt.HeadType {
-			case objabi.Hlinux:
-				if objabi.GOOS == "android" {
-					interpreter = thearch.Androiddynld
-					if interpreter == "" {
-						Exitf("ELF interpreter not set")
-					}
-				} else {
-					interpreter = thearch.Linuxdynld
-				}
-
-			case objabi.Hfreebsd:
-				interpreter = thearch.Freebsddynld
-
-			case objabi.Hnetbsd:
-				interpreter = thearch.Netbsddynld
-
-			case objabi.Hopenbsd:
-				interpreter = thearch.Openbsddynld
-
-			case objabi.Hdragonfly:
-				interpreter = thearch.Dragonflydynld
-
-			case objabi.Hsolaris:
-				interpreter = thearch.Solarisdynld
-			}
-		}
-
-		resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter))
-
-		ph := newElfPhdr()
-		ph.type_ = PT_INTERP
-		ph.flags = PF_R
-		phsh(ph, sh)
-	}
-
-	pnote = nil
-	if ctxt.HeadType == objabi.Hnetbsd || ctxt.HeadType == objabi.Hopenbsd {
-		var sh *ElfShdr
-		switch ctxt.HeadType {
-		case objabi.Hnetbsd:
-			sh = elfshname(".note.netbsd.ident")
-			resoff -= int64(elfnetbsdsig(sh, uint64(startva), uint64(resoff)))
-
-		case objabi.Hopenbsd:
-			sh = elfshname(".note.openbsd.ident")
-			resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff)))
-		}
-
-		pnote = newElfPhdr()
-		pnote.type_ = PT_NOTE
-		pnote.flags = PF_R
-		phsh(pnote, sh)
-	}
-
-	if len(buildinfo) > 0 {
-		sh := elfshname(".note.gnu.build-id")
-		resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff)))
-
-		if pnote == nil {
-			pnote = newElfPhdr()
-			pnote.type_ = PT_NOTE
-			pnote.flags = PF_R
-		}
-
-		phsh(pnote, sh)
-	}
-
-	if *flagBuildid != "" {
-		sh := elfshname(".note.go.buildid")
-		resoff -= int64(elfgobuildid(sh, uint64(startva), uint64(resoff)))
-
-		pnote := newElfPhdr()
-		pnote.type_ = PT_NOTE
-		pnote.flags = PF_R
-		phsh(pnote, sh)
-	}
-
-	// Additions to the reserved area must be above this line.
-
-	elfphload(&Segtext)
-	if len(Segrodata.Sections) > 0 {
-		elfphload(&Segrodata)
-	}
-	if len(Segrelrodata.Sections) > 0 {
-		elfphload(&Segrelrodata)
-		elfphrelro(&Segrelrodata)
-	}
-	elfphload(&Segdata)
-
-	/* Dynamic linking sections */
-	if !*FlagD {
-		sh := elfshname(".dynsym")
-		sh.type_ = SHT_DYNSYM
-		sh.flags = SHF_ALLOC
-		if elf64 {
-			sh.entsize = ELF64SYMSIZE
-		} else {
-			sh.entsize = ELF32SYMSIZE
-		}
-		sh.addralign = uint64(ctxt.Arch.RegSize)
-		sh.link = uint32(elfshname(".dynstr").shnum)
-
-		// sh.info is the index of first non-local symbol (number of local symbols)
-		s := ctxt.Syms.Lookup(".dynsym", 0)
-		i := uint32(0)
-		for sub := s; sub != nil; sub = sub.Sub {
-			i++
-			if !sub.Attr.Local() {
-				break
-			}
-		}
-		sh.info = i
-		shsym(sh, s)
-
-		sh = elfshname(".dynstr")
-		sh.type_ = SHT_STRTAB
-		sh.flags = SHF_ALLOC
-		sh.addralign = 1
-		shsym(sh, ctxt.Syms.Lookup(".dynstr", 0))
-
-		if elfverneed != 0 {
-			sh := elfshname(".gnu.version")
-			sh.type_ = SHT_GNU_VERSYM
-			sh.flags = SHF_ALLOC
-			sh.addralign = 2
-			sh.link = uint32(elfshname(".dynsym").shnum)
-			sh.entsize = 2
-			shsym(sh, ctxt.Syms.Lookup(".gnu.version", 0))
-
-			sh = elfshname(".gnu.version_r")
-			sh.type_ = SHT_GNU_VERNEED
-			sh.flags = SHF_ALLOC
-			sh.addralign = uint64(ctxt.Arch.RegSize)
-			sh.info = uint32(elfverneed)
-			sh.link = uint32(elfshname(".dynstr").shnum)
-			shsym(sh, ctxt.Syms.Lookup(".gnu.version_r", 0))
-		}
-
-		if elfRelType == ".rela" {
-			sh := elfshname(".rela.plt")
-			sh.type_ = SHT_RELA
-			sh.flags = SHF_ALLOC
-			sh.entsize = ELF64RELASIZE
-			sh.addralign = uint64(ctxt.Arch.RegSize)
-			sh.link = uint32(elfshname(".dynsym").shnum)
-			sh.info = uint32(elfshname(".plt").shnum)
-			shsym(sh, ctxt.Syms.Lookup(".rela.plt", 0))
-
-			sh = elfshname(".rela")
-			sh.type_ = SHT_RELA
-			sh.flags = SHF_ALLOC
-			sh.entsize = ELF64RELASIZE
-			sh.addralign = 8
-			sh.link = uint32(elfshname(".dynsym").shnum)
-			shsym(sh, ctxt.Syms.Lookup(".rela", 0))
-		} else {
-			sh := elfshname(".rel.plt")
-			sh.type_ = SHT_REL
-			sh.flags = SHF_ALLOC
-			sh.entsize = ELF32RELSIZE
-			sh.addralign = 4
-			sh.link = uint32(elfshname(".dynsym").shnum)
-			shsym(sh, ctxt.Syms.Lookup(".rel.plt", 0))
-
-			sh = elfshname(".rel")
-			sh.type_ = SHT_REL
-			sh.flags = SHF_ALLOC
-			sh.entsize = ELF32RELSIZE
-			sh.addralign = 4
-			sh.link = uint32(elfshname(".dynsym").shnum)
-			shsym(sh, ctxt.Syms.Lookup(".rel", 0))
-		}
-
-		if eh.machine == EM_PPC64 {
-			sh := elfshname(".glink")
-			sh.type_ = SHT_PROGBITS
-			sh.flags = SHF_ALLOC + SHF_EXECINSTR
-			sh.addralign = 4
-			shsym(sh, ctxt.Syms.Lookup(".glink", 0))
-		}
-
-		sh = elfshname(".plt")
-		sh.type_ = SHT_PROGBITS
-		sh.flags = SHF_ALLOC + SHF_EXECINSTR
-		if eh.machine == EM_X86_64 {
-			sh.entsize = 16
-		} else if eh.machine == EM_S390 {
-			sh.entsize = 32
-		} else if eh.machine == EM_PPC64 {
-			// On ppc64, this is just a table of addresses
-			// filled by the dynamic linker
-			sh.type_ = SHT_NOBITS
-
-			sh.flags = SHF_ALLOC + SHF_WRITE
-			sh.entsize = 8
-		} else {
-			sh.entsize = 4
-		}
-		sh.addralign = sh.entsize
-		shsym(sh, ctxt.Syms.Lookup(".plt", 0))
-
-		// On ppc64, .got comes from the input files, so don't
-		// create it here, and .got.plt is not used.
-		if eh.machine != EM_PPC64 {
-			sh := elfshname(".got")
-			sh.type_ = SHT_PROGBITS
-			sh.flags = SHF_ALLOC + SHF_WRITE
-			sh.entsize = uint64(ctxt.Arch.RegSize)
-			sh.addralign = uint64(ctxt.Arch.RegSize)
-			shsym(sh, ctxt.Syms.Lookup(".got", 0))
-
-			sh = elfshname(".got.plt")
-			sh.type_ = SHT_PROGBITS
-			sh.flags = SHF_ALLOC + SHF_WRITE
-			sh.entsize = uint64(ctxt.Arch.RegSize)
-			sh.addralign = uint64(ctxt.Arch.RegSize)
-			shsym(sh, ctxt.Syms.Lookup(".got.plt", 0))
-		}
-
-		sh = elfshname(".hash")
-		sh.type_ = SHT_HASH
-		sh.flags = SHF_ALLOC
-		sh.entsize = 4
-		sh.addralign = uint64(ctxt.Arch.RegSize)
-		sh.link = uint32(elfshname(".dynsym").shnum)
-		shsym(sh, ctxt.Syms.Lookup(".hash", 0))
-
-		/* sh and PT_DYNAMIC for .dynamic section */
-		sh = elfshname(".dynamic")
-
-		sh.type_ = SHT_DYNAMIC
-		sh.flags = SHF_ALLOC + SHF_WRITE
-		sh.entsize = 2 * uint64(ctxt.Arch.RegSize)
-		sh.addralign = uint64(ctxt.Arch.RegSize)
-		sh.link = uint32(elfshname(".dynstr").shnum)
-		shsym(sh, ctxt.Syms.Lookup(".dynamic", 0))
-		ph := newElfPhdr()
-		ph.type_ = PT_DYNAMIC
-		ph.flags = PF_R + PF_W
-		phsh(ph, sh)
-
-		/*
-		 * Thread-local storage segment (really just size).
-		 */
-		tlssize := uint64(0)
-		for _, sect := range Segdata.Sections {
-			if sect.Name == ".tbss" {
-				tlssize = sect.Length
-			}
-		}
-		if tlssize != 0 {
-			ph := newElfPhdr()
-			ph.type_ = PT_TLS
-			ph.flags = PF_R
-			ph.memsz = tlssize
-			ph.align = uint64(ctxt.Arch.RegSize)
-		}
-	}
-
-	if ctxt.HeadType == objabi.Hlinux {
-		ph := newElfPhdr()
-		ph.type_ = PT_GNU_STACK
-		ph.flags = PF_W + PF_R
-		ph.align = uint64(ctxt.Arch.RegSize)
-
-		ph = newElfPhdr()
-		ph.type_ = PT_PAX_FLAGS
-		ph.flags = 0x2a00 // mprotect, randexec, emutramp disabled
-		ph.align = uint64(ctxt.Arch.RegSize)
-	} else if ctxt.HeadType == objabi.Hsolaris {
-		ph := newElfPhdr()
-		ph.type_ = PT_SUNWSTACK
-		ph.flags = PF_W + PF_R
-	}
-
-elfobj:
-	sh := elfshname(".shstrtab")
-	sh.type_ = SHT_STRTAB
-	sh.addralign = 1
-	shsym(sh, ctxt.Syms.Lookup(".shstrtab", 0))
-	eh.shstrndx = uint16(sh.shnum)
-
-	// put these sections early in the list
-	if !*FlagS {
-		elfshname(".symtab")
-		elfshname(".strtab")
-	}
-
-	for _, sect := range Segtext.Sections {
-		elfshbits(ctxt.LinkMode, sect)
-	}
-	for _, sect := range Segrodata.Sections {
-		elfshbits(ctxt.LinkMode, sect)
-	}
-	for _, sect := range Segrelrodata.Sections {
-		elfshbits(ctxt.LinkMode, sect)
-	}
-	for _, sect := range Segdata.Sections {
-		elfshbits(ctxt.LinkMode, sect)
-	}
-	for _, sect := range Segdwarf.Sections {
-		elfshbits(ctxt.LinkMode, sect)
-	}
-
-	if ctxt.LinkMode == LinkExternal {
-		for _, sect := range Segtext.Sections {
-			elfshreloc(ctxt.Arch, sect)
-		}
-		for _, sect := range Segrodata.Sections {
-			elfshreloc(ctxt.Arch, sect)
-		}
-		for _, sect := range Segrelrodata.Sections {
-			elfshreloc(ctxt.Arch, sect)
-		}
-		for _, sect := range Segdata.Sections {
-			elfshreloc(ctxt.Arch, sect)
-		}
-		for _, s := range dwarfp {
-			if len(s.R) > 0 || s.Type == sym.SDWARFINFO || s.Type == sym.SDWARFLOC {
-				elfshreloc(ctxt.Arch, s.Sect)
-			}
-		}
-		// add a .note.GNU-stack section to mark the stack as non-executable
-		sh := elfshname(".note.GNU-stack")
-
-		sh.type_ = SHT_PROGBITS
-		sh.addralign = 1
-		sh.flags = 0
-	}
-
-	if !*FlagS {
-		sh := elfshname(".symtab")
-		sh.type_ = SHT_SYMTAB
-		sh.off = uint64(symo)
-		sh.size = uint64(Symsize)
-		sh.addralign = uint64(ctxt.Arch.RegSize)
-		sh.entsize = 8 + 2*uint64(ctxt.Arch.RegSize)
-		sh.link = uint32(elfshname(".strtab").shnum)
-		sh.info = uint32(elfglobalsymndx)
-
-		sh = elfshname(".strtab")
-		sh.type_ = SHT_STRTAB
-		sh.off = uint64(symo) + uint64(Symsize)
-		sh.size = uint64(len(Elfstrdat))
-		sh.addralign = 1
-	}
-
-	/* Main header */
-	eh.ident[EI_MAG0] = '\177'
-
-	eh.ident[EI_MAG1] = 'E'
-	eh.ident[EI_MAG2] = 'L'
-	eh.ident[EI_MAG3] = 'F'
-	if ctxt.HeadType == objabi.Hfreebsd {
-		eh.ident[EI_OSABI] = ELFOSABI_FREEBSD
-	} else if ctxt.HeadType == objabi.Hnetbsd {
-		eh.ident[EI_OSABI] = ELFOSABI_NETBSD
-	} else if ctxt.HeadType == objabi.Hopenbsd {
-		eh.ident[EI_OSABI] = ELFOSABI_OPENBSD
-	} else if ctxt.HeadType == objabi.Hdragonfly {
-		eh.ident[EI_OSABI] = ELFOSABI_NONE
-	}
-	if elf64 {
-		eh.ident[EI_CLASS] = ELFCLASS64
-	} else {
-		eh.ident[EI_CLASS] = ELFCLASS32
-	}
-	if ctxt.Arch.ByteOrder == binary.BigEndian {
-		eh.ident[EI_DATA] = ELFDATA2MSB
-	} else {
-		eh.ident[EI_DATA] = ELFDATA2LSB
-	}
-	eh.ident[EI_VERSION] = EV_CURRENT
-
-	if ctxt.LinkMode == LinkExternal {
-		eh.type_ = ET_REL
-	} else if ctxt.BuildMode == BuildModePIE {
-		eh.type_ = ET_DYN
-	} else {
-		eh.type_ = ET_EXEC
-	}
-
-	if ctxt.LinkMode != LinkExternal {
-		eh.entry = uint64(Entryvalue(ctxt))
-	}
-
-	eh.version = EV_CURRENT
-
-	if pph != nil {
-		pph.filesz = uint64(eh.phnum) * uint64(eh.phentsize)
-		pph.memsz = pph.filesz
-	}
-
-	ctxt.Out.SeekSet(0)
-	a := int64(0)
-	a += int64(elfwritehdr(ctxt.Out))
-	a += int64(elfwritephdrs(ctxt.Out))
-	a += int64(elfwriteshdrs(ctxt.Out))
-	if !*FlagD {
-		a += int64(elfwriteinterp(ctxt.Out))
-	}
-	if ctxt.LinkMode != LinkExternal {
-		if ctxt.HeadType == objabi.Hnetbsd {
-			a += int64(elfwritenetbsdsig(ctxt.Out))
-		}
-		if ctxt.HeadType == objabi.Hopenbsd {
-			a += int64(elfwriteopenbsdsig(ctxt.Out))
-		}
-		if len(buildinfo) > 0 {
-			a += int64(elfwritebuildinfo(ctxt.Out))
-		}
-		if *flagBuildid != "" {
-			a += int64(elfwritegobuildid(ctxt.Out))
-		}
-	}
-	if *flagRace && ctxt.HeadType == objabi.Hnetbsd {
-		a += int64(elfwritenetbsdpax(ctxt.Out))
-	}
-
-	if a > elfreserve {
-		Errorf(nil, "ELFRESERVE too small: %d > %d with %d text sections", a, elfreserve, numtext)
-	}
-}
-
-func elfadddynsym(ctxt *Link, s *sym.Symbol) {
-	if elf64 {
-		s.Dynid = int32(Nelfsym)
-		Nelfsym++
-
-		d := ctxt.Syms.Lookup(".dynsym", 0)
-
-		name := s.Extname()
-		d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
-
-		/* type */
-		t := STB_GLOBAL << 4
-
-		if s.Attr.CgoExport() && s.Type == sym.STEXT {
-			t |= STT_FUNC
-		} else {
-			t |= STT_OBJECT
-		}
-		d.AddUint8(uint8(t))
-
-		/* reserved */
-		d.AddUint8(0)
-
-		/* section where symbol is defined */
-		if s.Type == sym.SDYNIMPORT {
-			d.AddUint16(ctxt.Arch, SHN_UNDEF)
-		} else {
-			d.AddUint16(ctxt.Arch, 1)
-		}
-
-		/* value */
-		if s.Type == sym.SDYNIMPORT {
-			d.AddUint64(ctxt.Arch, 0)
-		} else {
-			d.AddAddr(ctxt.Arch, s)
-		}
-
-		/* size of object */
-		d.AddUint64(ctxt.Arch, uint64(s.Size))
-
-		if ctxt.Arch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib() != "" && !seenlib[s.Dynimplib()] {
-			Elfwritedynent(ctxt, ctxt.Syms.Lookup(".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt.Syms.Lookup(".dynstr", 0), s.Dynimplib())))
-		}
-	} else {
-		s.Dynid = int32(Nelfsym)
-		Nelfsym++
-
-		d := ctxt.Syms.Lookup(".dynsym", 0)
-
-		/* name */
-		name := s.Extname()
-
-		d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
-
-		/* value */
-		if s.Type == sym.SDYNIMPORT {
-			d.AddUint32(ctxt.Arch, 0)
-		} else {
-			d.AddAddr(ctxt.Arch, s)
-		}
-
-		/* size of object */
-		d.AddUint32(ctxt.Arch, uint32(s.Size))
-
-		/* type */
-		t := STB_GLOBAL << 4
-
-		// TODO(mwhudson): presumably the behavior should actually be the same on both arm and 386.
-		if ctxt.Arch.Family == sys.I386 && s.Attr.CgoExport() && s.Type == sym.STEXT {
-			t |= STT_FUNC
-		} else if ctxt.Arch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type == sym.STEXT {
-			t |= STT_FUNC
-		} else {
-			t |= STT_OBJECT
-		}
-		d.AddUint8(uint8(t))
-		d.AddUint8(0)
-
-		/* shndx */
-		if s.Type == sym.SDYNIMPORT {
-			d.AddUint16(ctxt.Arch, SHN_UNDEF)
-		} else {
-			d.AddUint16(ctxt.Arch, 1)
-		}
-	}
-}
-
-func ELF32_R_SYM(info uint32) uint32 {
-	return info >> 8
-}
-
-func ELF32_R_TYPE(info uint32) uint32 {
-	return uint32(uint8(info))
-}
-
-func ELF32_R_INFO(sym uint32, type_ uint32) uint32 {
-	return sym<<8 | type_
-}
-
-func ELF32_ST_BIND(info uint8) uint8 {
-	return info >> 4
-}
-
-func ELF32_ST_TYPE(info uint8) uint8 {
-	return info & 0xf
-}
-
-func ELF32_ST_INFO(bind uint8, type_ uint8) uint8 {
-	return bind<<4 | type_&0xf
-}
-
-func ELF32_ST_VISIBILITY(oth uint8) uint8 {
-	return oth & 3
-}
-
-func ELF64_R_SYM(info uint64) uint32 {
-	return uint32(info >> 32)
-}
-
-func ELF64_R_TYPE(info uint64) uint32 {
-	return uint32(info)
-}
-
-func ELF64_R_INFO(sym uint32, type_ uint32) uint64 {
-	return uint64(sym)<<32 | uint64(type_)
-}
-
-func ELF64_ST_BIND(info uint8) uint8 {
-	return info >> 4
-}
-
-func ELF64_ST_TYPE(info uint8) uint8 {
-	return info & 0xf
-}
-
-func ELF64_ST_INFO(bind uint8, type_ uint8) uint8 {
-	return bind<<4 | type_&0xf
-}
-
-func ELF64_ST_VISIBILITY(oth uint8) uint8 {
-	return oth & 3
-}
diff --git a/src/cmd/oldlink/internal/ld/execarchive.go b/src/cmd/oldlink/internal/ld/execarchive.go
deleted file mode 100644
index fe5cc40..0000000
--- a/src/cmd/oldlink/internal/ld/execarchive.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2019 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 !wasm,!windows
-
-package ld
-
-import (
-	"os"
-	"os/exec"
-	"path/filepath"
-	"syscall"
-)
-
-const syscallExecSupported = true
-
-// execArchive invokes the archiver tool with syscall.Exec(), with
-// the expectation that this is the last thing that takes place
-// in the linking operation.
-func (ctxt *Link) execArchive(argv []string) {
-	var err error
-	argv0 := argv[0]
-	if filepath.Base(argv0) == argv0 {
-		argv0, err = exec.LookPath(argv0)
-		if err != nil {
-			Exitf("cannot find %s: %v", argv[0], err)
-		}
-	}
-	if ctxt.Debugvlog != 0 {
-		ctxt.Logf("invoking archiver with syscall.Exec()\n")
-	}
-	err = syscall.Exec(argv0, argv, os.Environ())
-	if err != nil {
-		Exitf("running %s failed: %v", argv[0], err)
-	}
-}
diff --git a/src/cmd/oldlink/internal/ld/execarchive_noexec.go b/src/cmd/oldlink/internal/ld/execarchive_noexec.go
deleted file mode 100644
index a70dea9..0000000
--- a/src/cmd/oldlink/internal/ld/execarchive_noexec.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2019 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 wasm windows
-
-package ld
-
-const syscallExecSupported = false
-
-func (ctxt *Link) execArchive(argv []string) {
-	panic("should never arrive here")
-}
diff --git a/src/cmd/oldlink/internal/ld/go.go b/src/cmd/oldlink/internal/ld/go.go
deleted file mode 100644
index b052655..0000000
--- a/src/cmd/oldlink/internal/ld/go.go
+++ /dev/null
@@ -1,442 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// go-specific code shared across loaders (5l, 6l, 8l).
-
-package ld
-
-import (
-	"bytes"
-	"cmd/internal/bio"
-	"cmd/internal/objabi"
-	"cmd/oldlink/internal/sym"
-	"encoding/json"
-	"fmt"
-	"io"
-	"os"
-	"strings"
-)
-
-// go-specific code shared across loaders (5l, 6l, 8l).
-
-// replace all "". with pkg.
-func expandpkg(t0 string, pkg string) string {
-	return strings.Replace(t0, `"".`, pkg+".", -1)
-}
-
-func resolveABIAlias(s *sym.Symbol) *sym.Symbol {
-	if s.Type != sym.SABIALIAS {
-		return s
-	}
-	target := s.R[0].Sym
-	if target.Type == sym.SABIALIAS {
-		panic(fmt.Sprintf("ABI alias %s references another ABI alias %s", s, target))
-	}
-	return target
-}
-
-// TODO:
-//	generate debugging section in binary.
-//	once the dust settles, try to move some code to
-//		libmach, so that other linkers and ar can share.
-
-func ldpkg(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, filename string) {
-	if *flagG {
-		return
-	}
-
-	if int64(int(length)) != length {
-		fmt.Fprintf(os.Stderr, "%s: too much pkg data in %s\n", os.Args[0], filename)
-		if *flagU {
-			errorexit()
-		}
-		return
-	}
-
-	bdata := make([]byte, length)
-	if _, err := io.ReadFull(f, bdata); err != nil {
-		fmt.Fprintf(os.Stderr, "%s: short pkg read %s\n", os.Args[0], filename)
-		if *flagU {
-			errorexit()
-		}
-		return
-	}
-	data := string(bdata)
-
-	// process header lines
-	for data != "" {
-		var line string
-		if i := strings.Index(data, "\n"); i >= 0 {
-			line, data = data[:i], data[i+1:]
-		} else {
-			line, data = data, ""
-		}
-		if line == "safe" {
-			lib.Safe = true
-		}
-		if line == "main" {
-			lib.Main = true
-		}
-		if line == "" {
-			break
-		}
-	}
-
-	// look for cgo section
-	p0 := strings.Index(data, "\n$$  // cgo")
-	var p1 int
-	if p0 >= 0 {
-		p0 += p1
-		i := strings.IndexByte(data[p0+1:], '\n')
-		if i < 0 {
-			fmt.Fprintf(os.Stderr, "%s: found $$ // cgo but no newline in %s\n", os.Args[0], filename)
-			if *flagU {
-				errorexit()
-			}
-			return
-		}
-		p0 += 1 + i
-
-		p1 = strings.Index(data[p0:], "\n$$")
-		if p1 < 0 {
-			p1 = strings.Index(data[p0:], "\n!\n")
-		}
-		if p1 < 0 {
-			fmt.Fprintf(os.Stderr, "%s: cannot find end of // cgo section in %s\n", os.Args[0], filename)
-			if *flagU {
-				errorexit()
-			}
-			return
-		}
-		p1 += p0
-		loadcgo(ctxt, filename, objabi.PathToPrefix(lib.Pkg), data[p0:p1])
-	}
-}
-
-func loadcgo(ctxt *Link, file string, pkg string, p string) {
-	var directives [][]string
-	if err := json.NewDecoder(strings.NewReader(p)).Decode(&directives); err != nil {
-		fmt.Fprintf(os.Stderr, "%s: %s: failed decoding cgo directives: %v\n", os.Args[0], file, err)
-		nerrors++
-		return
-	}
-
-	// Find cgo_export symbols. They are roots in the deadcode pass.
-	for _, f := range directives {
-		switch f[0] {
-		case "cgo_export_static", "cgo_export_dynamic":
-			if len(f) < 2 || len(f) > 3 {
-				continue
-			}
-			local := f[1]
-			switch ctxt.BuildMode {
-			case BuildModeCShared, BuildModeCArchive, BuildModePlugin:
-				if local == "main" {
-					continue
-				}
-			}
-			local = expandpkg(local, pkg)
-			if f[0] == "cgo_export_static" {
-				ctxt.cgo_export_static[local] = true
-			} else {
-				ctxt.cgo_export_dynamic[local] = true
-			}
-		}
-	}
-
-	if *flagNewobj {
-		// Record the directives. We'll process them later after Symbols are created.
-		ctxt.cgodata = append(ctxt.cgodata, cgodata{file, pkg, directives})
-	} else {
-		setCgoAttr(ctxt, ctxt.Syms.Lookup, file, pkg, directives)
-	}
-}
-
-// Set symbol attributes or flags based on cgo directives.
-func setCgoAttr(ctxt *Link, lookup func(string, int) *sym.Symbol, file string, pkg string, directives [][]string) {
-	for _, f := range directives {
-		switch f[0] {
-		case "cgo_import_dynamic":
-			if len(f) < 2 || len(f) > 4 {
-				break
-			}
-
-			local := f[1]
-			remote := local
-			if len(f) > 2 {
-				remote = f[2]
-			}
-			lib := ""
-			if len(f) > 3 {
-				lib = f[3]
-			}
-
-			if *FlagD {
-				fmt.Fprintf(os.Stderr, "%s: %s: cannot use dynamic imports with -d flag\n", os.Args[0], file)
-				nerrors++
-				return
-			}
-
-			if local == "_" && remote == "_" {
-				// allow #pragma dynimport _ _ "foo.so"
-				// to force a link of foo.so.
-				havedynamic = 1
-
-				if ctxt.HeadType == objabi.Hdarwin {
-					machoadddynlib(lib, ctxt.LinkMode)
-				} else {
-					dynlib = append(dynlib, lib)
-				}
-				continue
-			}
-
-			local = expandpkg(local, pkg)
-			q := ""
-			if i := strings.Index(remote, "#"); i >= 0 {
-				remote, q = remote[:i], remote[i+1:]
-			}
-			s := lookup(local, 0)
-			if s.Type == 0 || s.Type == sym.SXREF || s.Type == sym.SBSS || s.Type == sym.SNOPTRBSS || s.Type == sym.SHOSTOBJ {
-				s.SetDynimplib(lib)
-				s.SetExtname(remote)
-				s.SetDynimpvers(q)
-				if s.Type != sym.SHOSTOBJ {
-					s.Type = sym.SDYNIMPORT
-				}
-				havedynamic = 1
-			}
-
-			continue
-
-		case "cgo_import_static":
-			if len(f) != 2 {
-				break
-			}
-			local := f[1]
-
-			s := lookup(local, 0)
-			s.Type = sym.SHOSTOBJ
-			s.Size = 0
-			continue
-
-		case "cgo_export_static", "cgo_export_dynamic":
-			if len(f) < 2 || len(f) > 3 {
-				break
-			}
-			local := f[1]
-			remote := local
-			if len(f) > 2 {
-				remote = f[2]
-			}
-			local = expandpkg(local, pkg)
-
-			// The compiler arranges for an ABI0 wrapper
-			// to be available for all cgo-exported
-			// functions. Link.loadlib will resolve any
-			// ABI aliases we find here (since we may not
-			// yet know it's an alias).
-			s := lookup(local, 0)
-
-			switch ctxt.BuildMode {
-			case BuildModeCShared, BuildModeCArchive, BuildModePlugin:
-				if s == lookup("main", 0) {
-					continue
-				}
-			}
-
-			// export overrides import, for openbsd/cgo.
-			// see issue 4878.
-			if s.Dynimplib() != "" {
-				s.ResetDyninfo()
-				s.SetExtname("")
-				s.Type = 0
-			}
-
-			if !s.Attr.CgoExport() {
-				s.SetExtname(remote)
-			} else if s.Extname() != remote {
-				fmt.Fprintf(os.Stderr, "%s: conflicting cgo_export directives: %s as %s and %s\n", os.Args[0], s.Name, s.Extname(), remote)
-				nerrors++
-				return
-			}
-
-			if f[0] == "cgo_export_static" {
-				s.Attr |= sym.AttrCgoExportStatic
-			} else {
-				s.Attr |= sym.AttrCgoExportDynamic
-			}
-			continue
-
-		case "cgo_dynamic_linker":
-			if len(f) != 2 {
-				break
-			}
-
-			if *flagInterpreter == "" {
-				if interpreter != "" && interpreter != f[1] {
-					fmt.Fprintf(os.Stderr, "%s: conflict dynlinker: %s and %s\n", os.Args[0], interpreter, f[1])
-					nerrors++
-					return
-				}
-
-				interpreter = f[1]
-			}
-			continue
-
-		case "cgo_ldflag":
-			if len(f) != 2 {
-				break
-			}
-			ldflag = append(ldflag, f[1])
-			continue
-		}
-
-		fmt.Fprintf(os.Stderr, "%s: %s: invalid cgo directive: %q\n", os.Args[0], file, f)
-		nerrors++
-	}
-}
-
-var seenlib = make(map[string]bool)
-
-func adddynlib(ctxt *Link, lib string) {
-	if seenlib[lib] || ctxt.LinkMode == LinkExternal {
-		return
-	}
-	seenlib[lib] = true
-
-	if ctxt.IsELF {
-		s := ctxt.Syms.Lookup(".dynstr", 0)
-		if s.Size == 0 {
-			Addstring(s, "")
-		}
-		Elfwritedynent(ctxt, ctxt.Syms.Lookup(".dynamic", 0), DT_NEEDED, uint64(Addstring(s, lib)))
-	} else {
-		Errorf(nil, "adddynlib: unsupported binary format")
-	}
-}
-
-func Adddynsym(ctxt *Link, s *sym.Symbol) {
-	if s.Dynid >= 0 || ctxt.LinkMode == LinkExternal {
-		return
-	}
-
-	if ctxt.IsELF {
-		elfadddynsym(ctxt, s)
-	} else if ctxt.HeadType == objabi.Hdarwin {
-		Errorf(s, "adddynsym: missed symbol (Extname=%s)", s.Extname())
-	} else if ctxt.HeadType == objabi.Hwindows {
-		// already taken care of
-	} else {
-		Errorf(s, "adddynsym: unsupported binary format")
-	}
-}
-
-func fieldtrack(ctxt *Link) {
-	// record field tracking references
-	var buf bytes.Buffer
-	for _, s := range ctxt.Syms.Allsym {
-		if strings.HasPrefix(s.Name, "go.track.") {
-			s.Attr |= sym.AttrSpecial // do not lay out in data segment
-			s.Attr |= sym.AttrNotInSymbolTable
-			if s.Attr.Reachable() {
-				buf.WriteString(s.Name[9:])
-				for p := ctxt.Reachparent[s]; p != nil; p = ctxt.Reachparent[p] {
-					buf.WriteString("\t")
-					buf.WriteString(p.Name)
-				}
-				buf.WriteString("\n")
-			}
-
-			s.Type = sym.SCONST
-			s.Value = 0
-		}
-	}
-
-	if *flagFieldTrack == "" {
-		return
-	}
-	s := ctxt.Syms.ROLookup(*flagFieldTrack, 0)
-	if s == nil || !s.Attr.Reachable() {
-		return
-	}
-	s.Type = sym.SDATA
-	addstrdata(ctxt, *flagFieldTrack, buf.String())
-}
-
-func (ctxt *Link) addexport() {
-	// Track undefined external symbols during external link.
-	if ctxt.LinkMode == LinkExternal {
-		for _, s := range ctxt.Syms.Allsym {
-			if !s.Attr.Reachable() || s.Attr.Special() || s.Attr.SubSymbol() {
-				continue
-			}
-			if s.Type != sym.STEXT {
-				continue
-			}
-			for i := range s.R {
-				r := &s.R[i]
-				if r.Sym != nil && r.Sym.Type == sym.Sxxx {
-					r.Sym.Type = sym.SUNDEFEXT
-				}
-			}
-		}
-	}
-
-	// TODO(aix)
-	if ctxt.HeadType == objabi.Hdarwin || ctxt.HeadType == objabi.Haix {
-		return
-	}
-
-	for _, exp := range dynexp {
-		Adddynsym(ctxt, exp)
-	}
-	for _, lib := range dynlib {
-		adddynlib(ctxt, lib)
-	}
-}
-
-type Pkg struct {
-	mark    bool
-	checked bool
-	path    string
-	impby   []*Pkg
-}
-
-var pkgall []*Pkg
-
-func (p *Pkg) cycle() *Pkg {
-	if p.checked {
-		return nil
-	}
-
-	if p.mark {
-		nerrors++
-		fmt.Printf("import cycle:\n")
-		fmt.Printf("\t%s\n", p.path)
-		return p
-	}
-
-	p.mark = true
-	for _, q := range p.impby {
-		if bad := q.cycle(); bad != nil {
-			p.mark = false
-			p.checked = true
-			fmt.Printf("\timports %s\n", p.path)
-			if bad == p {
-				return nil
-			}
-			return bad
-		}
-	}
-
-	p.checked = true
-	p.mark = false
-	return nil
-}
-
-func importcycles() {
-	for _, p := range pkgall {
-		p.cycle()
-	}
-}
diff --git a/src/cmd/oldlink/internal/ld/ld.go b/src/cmd/oldlink/internal/ld/ld.go
deleted file mode 100644
index 7420dce..0000000
--- a/src/cmd/oldlink/internal/ld/ld.go
+++ /dev/null
@@ -1,217 +0,0 @@
-// Derived from Inferno utils/6l/obj.c and utils/6l/span.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ld
-
-import (
-	"cmd/oldlink/internal/sym"
-	"io/ioutil"
-	"log"
-	"os"
-	"path"
-	"path/filepath"
-	"strconv"
-	"strings"
-)
-
-func (ctxt *Link) readImportCfg(file string) {
-	ctxt.PackageFile = make(map[string]string)
-	ctxt.PackageShlib = make(map[string]string)
-	data, err := ioutil.ReadFile(file)
-	if err != nil {
-		log.Fatalf("-importcfg: %v", err)
-	}
-
-	for lineNum, line := range strings.Split(string(data), "\n") {
-		lineNum++ // 1-based
-		line = strings.TrimSpace(line)
-		if line == "" {
-			continue
-		}
-		if line == "" || strings.HasPrefix(line, "#") {
-			continue
-		}
-
-		var verb, args string
-		if i := strings.Index(line, " "); i < 0 {
-			verb = line
-		} else {
-			verb, args = line[:i], strings.TrimSpace(line[i+1:])
-		}
-		var before, after string
-		if i := strings.Index(args, "="); i >= 0 {
-			before, after = args[:i], args[i+1:]
-		}
-		switch verb {
-		default:
-			log.Fatalf("%s:%d: unknown directive %q", file, lineNum, verb)
-		case "packagefile":
-			if before == "" || after == "" {
-				log.Fatalf(`%s:%d: invalid packagefile: syntax is "packagefile path=filename"`, file, lineNum)
-			}
-			ctxt.PackageFile[before] = after
-		case "packageshlib":
-			if before == "" || after == "" {
-				log.Fatalf(`%s:%d: invalid packageshlib: syntax is "packageshlib path=filename"`, file, lineNum)
-			}
-			ctxt.PackageShlib[before] = after
-		}
-	}
-}
-
-func pkgname(ctxt *Link, lib string) string {
-	name := path.Clean(lib)
-
-	// When using importcfg, we have the final package name.
-	if ctxt.PackageFile != nil {
-		return name
-	}
-
-	// runtime.a -> runtime, runtime.6 -> runtime
-	pkg := name
-	if len(pkg) >= 2 && pkg[len(pkg)-2] == '.' {
-		pkg = pkg[:len(pkg)-2]
-	}
-	return pkg
-}
-
-func findlib(ctxt *Link, lib string) (string, bool) {
-	name := path.Clean(lib)
-
-	var pname string
-	isshlib := false
-
-	if ctxt.linkShared && ctxt.PackageShlib[name] != "" {
-		pname = ctxt.PackageShlib[name]
-		isshlib = true
-	} else if ctxt.PackageFile != nil {
-		pname = ctxt.PackageFile[name]
-		if pname == "" {
-			ctxt.Logf("cannot find package %s (using -importcfg)\n", name)
-			return "", false
-		}
-	} else {
-		if filepath.IsAbs(name) {
-			pname = name
-		} else {
-			pkg := pkgname(ctxt, lib)
-			// Add .a if needed; the new -importcfg modes
-			// do not put .a into the package name anymore.
-			// This only matters when people try to mix
-			// compiles using -importcfg with links not using -importcfg,
-			// such as when running quick things like
-			// 'go tool compile x.go && go tool link x.o'
-			// by hand against a standard library built using -importcfg.
-			if !strings.HasSuffix(name, ".a") && !strings.HasSuffix(name, ".o") {
-				name += ".a"
-			}
-			// try dot, -L "libdir", and then goroot.
-			for _, dir := range ctxt.Libdir {
-				if ctxt.linkShared {
-					pname = filepath.Join(dir, pkg+".shlibname")
-					if _, err := os.Stat(pname); err == nil {
-						isshlib = true
-						break
-					}
-				}
-				pname = filepath.Join(dir, name)
-				if _, err := os.Stat(pname); err == nil {
-					break
-				}
-			}
-		}
-		pname = filepath.Clean(pname)
-	}
-
-	return pname, isshlib
-}
-
-func addlib(ctxt *Link, src string, obj string, lib string) *sym.Library {
-	pkg := pkgname(ctxt, lib)
-
-	// already loaded?
-	if l := ctxt.LibraryByPkg[pkg]; l != nil {
-		return l
-	}
-
-	pname, isshlib := findlib(ctxt, lib)
-
-	if ctxt.Debugvlog > 1 {
-		ctxt.Logf("addlib: %s %s pulls in %s isshlib %v\n", obj, src, pname, isshlib)
-	}
-
-	if isshlib {
-		return addlibpath(ctxt, src, obj, "", pkg, pname)
-	}
-	return addlibpath(ctxt, src, obj, pname, pkg, "")
-}
-
-/*
- * add library to library list, return added library.
- *	srcref: src file referring to package
- *	objref: object file referring to package
- *	file: object file, e.g., /home/rsc/go/pkg/container/vector.a
- *	pkg: package import path, e.g. container/vector
- *	shlib: path to shared library, or .shlibname file holding path
- */
-func addlibpath(ctxt *Link, srcref string, objref string, file string, pkg string, shlib string) *sym.Library {
-	if l := ctxt.LibraryByPkg[pkg]; l != nil {
-		return l
-	}
-
-	if ctxt.Debugvlog > 1 {
-		ctxt.Logf("addlibpath: srcref: %s objref: %s file: %s pkg: %s shlib: %s\n", srcref, objref, file, pkg, shlib)
-	}
-
-	l := &sym.Library{}
-	ctxt.LibraryByPkg[pkg] = l
-	ctxt.Library = append(ctxt.Library, l)
-	l.Objref = objref
-	l.Srcref = srcref
-	l.File = file
-	l.Pkg = pkg
-	if shlib != "" {
-		if strings.HasSuffix(shlib, ".shlibname") {
-			data, err := ioutil.ReadFile(shlib)
-			if err != nil {
-				Errorf(nil, "cannot read %s: %v", shlib, err)
-			}
-			shlib = strings.TrimSpace(string(data))
-		}
-		l.Shlib = shlib
-	}
-	return l
-}
-
-func atolwhex(s string) int64 {
-	n, _ := strconv.ParseInt(s, 0, 64)
-	return n
-}
diff --git a/src/cmd/oldlink/internal/ld/lib.go b/src/cmd/oldlink/internal/ld/lib.go
deleted file mode 100644
index 0fc786f..0000000
--- a/src/cmd/oldlink/internal/ld/lib.go
+++ /dev/null
@@ -1,2749 +0,0 @@
-// Inferno utils/8l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/8l/asm.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ld
-
-import (
-	"bufio"
-	"bytes"
-	"cmd/internal/bio"
-	"cmd/internal/obj"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/loadelf"
-	"cmd/oldlink/internal/loader"
-	"cmd/oldlink/internal/loadmacho"
-	"cmd/oldlink/internal/loadpe"
-	"cmd/oldlink/internal/loadxcoff"
-	"cmd/oldlink/internal/objfile"
-	"cmd/oldlink/internal/sym"
-	"crypto/sha1"
-	"debug/elf"
-	"debug/macho"
-	"encoding/base64"
-	"encoding/binary"
-	"encoding/hex"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"runtime"
-	"sort"
-	"strings"
-	"sync"
-)
-
-// Data layout and relocation.
-
-// Derived from Inferno utils/6l/l.h
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-type Arch struct {
-	Funcalign      int
-	Maxalign       int
-	Minalign       int
-	Dwarfregsp     int
-	Dwarfreglr     int
-	Androiddynld   string
-	Linuxdynld     string
-	Freebsddynld   string
-	Netbsddynld    string
-	Openbsddynld   string
-	Dragonflydynld string
-	Solarisdynld   string
-	Adddynrel      func(*Link, *sym.Symbol, *sym.Reloc) bool
-	Archinit       func(*Link)
-	// Archreloc is an arch-specific hook that assists in
-	// relocation processing (invoked by 'relocsym'); it handles
-	// target-specific relocation tasks. Here "rel" is the current
-	// relocation being examined, "sym" is the symbol containing the
-	// chunk of data to which the relocation applies, and "off" is the
-	// contents of the to-be-relocated data item (from sym.P). Return
-	// value is the appropriately relocated value (to be written back
-	// to the same spot in sym.P) and a boolean indicating
-	// success/failure (a failing value indicates a fatal error).
-	Archreloc func(link *Link, rel *sym.Reloc, sym *sym.Symbol,
-		offset int64) (relocatedOffset int64, success bool)
-	// Archrelocvariant is a second arch-specific hook used for
-	// relocation processing; it handles relocations where r.Type is
-	// insufficient to describe the relocation (r.Variant !=
-	// sym.RV_NONE). Here "rel" is the relocation being applied, "sym"
-	// is the symbol containing the chunk of data to which the
-	// relocation applies, and "off" is the contents of the
-	// to-be-relocated data item (from sym.P). Return is an updated
-	// offset value.
-	Archrelocvariant func(link *Link, rel *sym.Reloc, sym *sym.Symbol,
-		offset int64) (relocatedOffset int64)
-	Trampoline func(*Link, *sym.Reloc, *sym.Symbol)
-
-	// Asmb and Asmb2 are arch-specific routines that write the output
-	// file. Typically, Asmb writes most of the content (sections and
-	// segments), for which we have computed the size and offset. Asmb2
-	// writes the rest.
-	Asmb  func(*Link)
-	Asmb2 func(*Link)
-
-	Elfreloc1   func(*Link, *sym.Reloc, int64) bool
-	Elfsetupplt func(*Link)
-	Gentext     func(*Link)
-	Machoreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
-	PEreloc1    func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
-	Xcoffreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
-
-	// TLSIEtoLE converts a TLS Initial Executable relocation to
-	// a TLS Local Executable relocation.
-	//
-	// This is possible when a TLS IE relocation refers to a local
-	// symbol in an executable, which is typical when internally
-	// linking PIE binaries.
-	TLSIEtoLE func(s *sym.Symbol, off, size int)
-
-	// optional override for assignAddress
-	AssignAddress func(ctxt *Link, sect *sym.Section, n int, s *sym.Symbol, va uint64, isTramp bool) (*sym.Section, int, uint64)
-}
-
-var (
-	thearch Arch
-	Lcsize  int32
-	rpath   Rpath
-	Spsize  int32
-	Symsize int32
-)
-
-const (
-	MINFUNC = 16 // minimum size for a function
-)
-
-// DynlinkingGo reports whether we are producing Go code that can live
-// in separate shared libraries linked together at runtime.
-func (ctxt *Link) DynlinkingGo() bool {
-	if !ctxt.Loaded {
-		panic("DynlinkingGo called before all symbols loaded")
-	}
-	return ctxt.BuildMode == BuildModeShared || ctxt.linkShared || ctxt.BuildMode == BuildModePlugin || ctxt.canUsePlugins
-}
-
-// CanUsePlugins reports whether a plugins can be used
-func (ctxt *Link) CanUsePlugins() bool {
-	if !ctxt.Loaded {
-		panic("CanUsePlugins called before all symbols loaded")
-	}
-	return ctxt.canUsePlugins
-}
-
-// UseRelro reports whether to make use of "read only relocations" aka
-// relro.
-func (ctxt *Link) UseRelro() bool {
-	switch ctxt.BuildMode {
-	case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePIE, BuildModePlugin:
-		return ctxt.IsELF || ctxt.HeadType == objabi.Haix
-	default:
-		return ctxt.linkShared || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal)
-	}
-}
-
-var (
-	dynexp          []*sym.Symbol
-	dynlib          []string
-	ldflag          []string
-	havedynamic     int
-	Funcalign       int
-	iscgo           bool
-	elfglobalsymndx int
-	interpreter     string
-
-	debug_s bool // backup old value of debug['s']
-	HEADR   int32
-
-	nerrors  int
-	liveness int64
-
-	// See -strictdups command line flag.
-	checkStrictDups   int // 0=off 1=warning 2=error
-	strictDupMsgCount int
-)
-
-var (
-	Segtext      sym.Segment
-	Segrodata    sym.Segment
-	Segrelrodata sym.Segment
-	Segdata      sym.Segment
-	Segdwarf     sym.Segment
-)
-
-const pkgdef = "__.PKGDEF"
-
-var (
-	// Set if we see an object compiled by the host compiler that is not
-	// from a package that is known to support internal linking mode.
-	externalobj = false
-	theline     string
-)
-
-func Lflag(ctxt *Link, arg string) {
-	ctxt.Libdir = append(ctxt.Libdir, arg)
-}
-
-/*
- * Unix doesn't like it when we write to a running (or, sometimes,
- * recently run) binary, so remove the output file before writing it.
- * On Windows 7, remove() can force a subsequent create() to fail.
- * S_ISREG() does not exist on Plan 9.
- */
-func mayberemoveoutfile() {
-	if fi, err := os.Lstat(*flagOutfile); err == nil && !fi.Mode().IsRegular() {
-		return
-	}
-	os.Remove(*flagOutfile)
-}
-
-func libinit(ctxt *Link) {
-	Funcalign = thearch.Funcalign
-
-	// add goroot to the end of the libdir list.
-	suffix := ""
-
-	suffixsep := ""
-	if *flagInstallSuffix != "" {
-		suffixsep = "_"
-		suffix = *flagInstallSuffix
-	} else if *flagRace {
-		suffixsep = "_"
-		suffix = "race"
-	} else if *flagMsan {
-		suffixsep = "_"
-		suffix = "msan"
-	}
-
-	Lflag(ctxt, filepath.Join(objabi.GOROOT, "pkg", fmt.Sprintf("%s_%s%s%s", objabi.GOOS, objabi.GOARCH, suffixsep, suffix)))
-
-	mayberemoveoutfile()
-	f, err := os.OpenFile(*flagOutfile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775)
-	if err != nil {
-		Exitf("cannot create %s: %v", *flagOutfile, err)
-	}
-
-	ctxt.Out.w = bufio.NewWriter(f)
-	ctxt.Out.f = f
-
-	if *flagEntrySymbol == "" {
-		switch ctxt.BuildMode {
-		case BuildModeCShared, BuildModeCArchive:
-			*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s_lib", objabi.GOARCH, objabi.GOOS)
-		case BuildModeExe, BuildModePIE:
-			*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s", objabi.GOARCH, objabi.GOOS)
-		case BuildModeShared, BuildModePlugin:
-			// No *flagEntrySymbol for -buildmode=shared and plugin
-		default:
-			Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", ctxt.BuildMode)
-		}
-	}
-}
-
-func exitIfErrors() {
-	if nerrors != 0 || checkStrictDups > 1 && strictDupMsgCount > 0 {
-		mayberemoveoutfile()
-		Exit(2)
-	}
-
-}
-
-func errorexit() {
-	exitIfErrors()
-	Exit(0)
-}
-
-func loadinternal(ctxt *Link, name string) *sym.Library {
-	if ctxt.linkShared && ctxt.PackageShlib != nil {
-		if shlib := ctxt.PackageShlib[name]; shlib != "" {
-			return addlibpath(ctxt, "internal", "internal", "", name, shlib)
-		}
-	}
-	if ctxt.PackageFile != nil {
-		if pname := ctxt.PackageFile[name]; pname != "" {
-			return addlibpath(ctxt, "internal", "internal", pname, name, "")
-		}
-		ctxt.Logf("loadinternal: cannot find %s\n", name)
-		return nil
-	}
-
-	for _, libdir := range ctxt.Libdir {
-		if ctxt.linkShared {
-			shlibname := filepath.Join(libdir, name+".shlibname")
-			if ctxt.Debugvlog != 0 {
-				ctxt.Logf("searching for %s.a in %s\n", name, shlibname)
-			}
-			if _, err := os.Stat(shlibname); err == nil {
-				return addlibpath(ctxt, "internal", "internal", "", name, shlibname)
-			}
-		}
-		pname := filepath.Join(libdir, name+".a")
-		if ctxt.Debugvlog != 0 {
-			ctxt.Logf("searching for %s.a in %s\n", name, pname)
-		}
-		if _, err := os.Stat(pname); err == nil {
-			return addlibpath(ctxt, "internal", "internal", pname, name, "")
-		}
-	}
-
-	ctxt.Logf("warning: unable to find %s.a\n", name)
-	return nil
-}
-
-// extld returns the current external linker.
-func (ctxt *Link) extld() string {
-	if *flagExtld == "" {
-		*flagExtld = "gcc"
-	}
-	return *flagExtld
-}
-
-// findLibPathCmd uses cmd command to find gcc library libname.
-// It returns library full path if found, or "none" if not found.
-func (ctxt *Link) findLibPathCmd(cmd, libname string) string {
-	extld := ctxt.extld()
-	args := hostlinkArchArgs(ctxt.Arch)
-	args = append(args, cmd)
-	if ctxt.Debugvlog != 0 {
-		ctxt.Logf("%s %v\n", extld, args)
-	}
-	out, err := exec.Command(extld, args...).Output()
-	if err != nil {
-		if ctxt.Debugvlog != 0 {
-			ctxt.Logf("not using a %s file because compiler failed\n%v\n%s\n", libname, err, out)
-		}
-		return "none"
-	}
-	return strings.TrimSpace(string(out))
-}
-
-// findLibPath searches for library libname.
-// It returns library full path if found, or "none" if not found.
-func (ctxt *Link) findLibPath(libname string) string {
-	return ctxt.findLibPathCmd("--print-file-name="+libname, libname)
-}
-
-func (ctxt *Link) loadlib() {
-	if *flagNewobj {
-		var flags uint32
-		switch *FlagStrictDups {
-		case 0:
-			// nothing to do
-		case 1, 2:
-			flags = loader.FlagStrictDups
-		default:
-			log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups)
-		}
-		ctxt.loader = loader.NewLoader(flags)
-	}
-
-	ctxt.cgo_export_static = make(map[string]bool)
-	ctxt.cgo_export_dynamic = make(map[string]bool)
-
-	// ctxt.Library grows during the loop, so not a range loop.
-	i := 0
-	for ; i < len(ctxt.Library); i++ {
-		lib := ctxt.Library[i]
-		if lib.Shlib == "" {
-			if ctxt.Debugvlog > 1 {
-				ctxt.Logf("autolib: %s (from %s)\n", lib.File, lib.Objref)
-			}
-			loadobjfile(ctxt, lib)
-		}
-	}
-
-	// load internal packages, if not already
-	if *flagRace {
-		loadinternal(ctxt, "runtime/race")
-	}
-	if *flagMsan {
-		loadinternal(ctxt, "runtime/msan")
-	}
-	loadinternal(ctxt, "runtime")
-	for ; i < len(ctxt.Library); i++ {
-		lib := ctxt.Library[i]
-		if lib.Shlib == "" {
-			loadobjfile(ctxt, lib)
-		}
-	}
-
-	if *flagNewobj {
-		iscgo = ctxt.loader.Lookup("x_cgo_init", 0) != 0
-		ctxt.canUsePlugins = ctxt.loader.Lookup("plugin.Open", sym.SymVerABIInternal) != 0
-	} else {
-		iscgo = ctxt.Syms.ROLookup("x_cgo_init", 0) != nil
-		ctxt.canUsePlugins = ctxt.Syms.ROLookup("plugin.Open", sym.SymVerABIInternal) != nil
-	}
-
-	// We now have enough information to determine the link mode.
-	determineLinkMode(ctxt)
-
-	if ctxt.LinkMode == LinkExternal && !iscgo && ctxt.LibraryByPkg["runtime/cgo"] == nil && !(objabi.GOOS == "darwin" && ctxt.BuildMode != BuildModePlugin && ctxt.Arch.Family == sys.AMD64) {
-		// This indicates a user requested -linkmode=external.
-		// The startup code uses an import of runtime/cgo to decide
-		// whether to initialize the TLS.  So give it one. This could
-		// be handled differently but it's an unusual case.
-		if lib := loadinternal(ctxt, "runtime/cgo"); lib != nil {
-			if lib.Shlib != "" {
-				ldshlibsyms(ctxt, lib.Shlib)
-			} else {
-				if ctxt.BuildMode == BuildModeShared || ctxt.linkShared {
-					Exitf("cannot implicitly include runtime/cgo in a shared library")
-				}
-				loadobjfile(ctxt, lib)
-			}
-		}
-	}
-
-	for _, lib := range ctxt.Library {
-		if lib.Shlib != "" {
-			if ctxt.Debugvlog > 1 {
-				ctxt.Logf("autolib: %s (from %s)\n", lib.Shlib, lib.Objref)
-			}
-			ldshlibsyms(ctxt, lib.Shlib)
-		}
-	}
-
-	if ctxt.LinkMode == LinkInternal && len(hostobj) != 0 {
-		if *flagNewobj {
-			// In newobj mode, we typically create sym.Symbols later therefore
-			// also set cgo attributes later. However, for internal cgo linking,
-			// the host object loaders still work with sym.Symbols (for now),
-			// and they need cgo attributes set to work properly. So process
-			// them now.
-			lookup := func(name string, ver int) *sym.Symbol { return ctxt.loader.LookupOrCreate(name, ver, ctxt.Syms) }
-			for _, d := range ctxt.cgodata {
-				setCgoAttr(ctxt, lookup, d.file, d.pkg, d.directives)
-			}
-			ctxt.cgodata = nil
-		}
-
-		// Drop all the cgo_import_static declarations.
-		// Turns out we won't be needing them.
-		for _, s := range ctxt.Syms.Allsym {
-			if s.Type == sym.SHOSTOBJ {
-				// If a symbol was marked both
-				// cgo_import_static and cgo_import_dynamic,
-				// then we want to make it cgo_import_dynamic
-				// now.
-				if s.Extname() != "" && s.Dynimplib() != "" && !s.Attr.CgoExport() {
-					s.Type = sym.SDYNIMPORT
-				} else {
-					s.Type = 0
-				}
-			}
-		}
-	}
-
-	// Conditionally load host objects, or setup for external linking.
-	hostobjs(ctxt)
-	hostlinksetup(ctxt)
-
-	if *flagNewobj {
-		// Add references of externally defined symbols.
-		ctxt.loader.LoadRefs(ctxt.Arch, ctxt.Syms)
-	}
-
-	// Now that we know the link mode, set the dynexp list.
-	if !*flagNewobj { // set this later in newobj mode
-		setupdynexp(ctxt)
-	}
-
-	if ctxt.LinkMode == LinkInternal && len(hostobj) != 0 {
-		// If we have any undefined symbols in external
-		// objects, try to read them from the libgcc file.
-		any := false
-		for _, s := range ctxt.Syms.Allsym {
-			for i := range s.R {
-				r := &s.R[i] // Copying sym.Reloc has measurable impact on performance
-				if r.Sym != nil && r.Sym.Type == sym.SXREF && r.Sym.Name != ".got" {
-					any = true
-					break
-				}
-			}
-		}
-		if any {
-			if *flagLibGCC == "" {
-				*flagLibGCC = ctxt.findLibPathCmd("--print-libgcc-file-name", "libgcc")
-			}
-			if runtime.GOOS == "openbsd" && *flagLibGCC == "libgcc.a" {
-				// On OpenBSD `clang --print-libgcc-file-name` returns "libgcc.a".
-				// In this case we fail to load libgcc.a and can encounter link
-				// errors - see if we can find libcompiler_rt.a instead.
-				*flagLibGCC = ctxt.findLibPathCmd("--print-file-name=libcompiler_rt.a", "libcompiler_rt")
-			}
-			if *flagLibGCC != "none" {
-				hostArchive(ctxt, *flagLibGCC)
-			}
-			if ctxt.HeadType == objabi.Hwindows {
-				if p := ctxt.findLibPath("libmingwex.a"); p != "none" {
-					hostArchive(ctxt, p)
-				}
-				if p := ctxt.findLibPath("libmingw32.a"); p != "none" {
-					hostArchive(ctxt, p)
-				}
-				// Link libmsvcrt.a to resolve '__acrt_iob_func' symbol
-				// (see https://golang.org/issue/23649 for details).
-				if p := ctxt.findLibPath("libmsvcrt.a"); p != "none" {
-					hostArchive(ctxt, p)
-				}
-				// TODO: maybe do something similar to peimporteddlls to collect all lib names
-				// and try link them all to final exe just like libmingwex.a and libmingw32.a:
-				/*
-					for:
-					#cgo windows LDFLAGS: -lmsvcrt -lm
-					import:
-					libmsvcrt.a libm.a
-				*/
-			}
-		}
-	}
-
-	// We've loaded all the code now.
-	ctxt.Loaded = true
-
-	importcycles()
-
-	if *flagNewobj {
-		strictDupMsgCount = ctxt.loader.NStrictDupMsgs()
-	}
-}
-
-// Set up dynexp list.
-func setupdynexp(ctxt *Link) {
-	dynexpMap := ctxt.cgo_export_dynamic
-	if ctxt.LinkMode == LinkExternal {
-		dynexpMap = ctxt.cgo_export_static
-	}
-	dynexp = make([]*sym.Symbol, 0, len(dynexpMap))
-	for exp := range dynexpMap {
-		s := ctxt.Syms.Lookup(exp, 0)
-		dynexp = append(dynexp, s)
-	}
-	sort.Sort(byName(dynexp))
-
-	// Resolve ABI aliases in the list of cgo-exported functions.
-	// This is necessary because we load the ABI0 symbol for all
-	// cgo exports.
-	for i, s := range dynexp {
-		if s.Type != sym.SABIALIAS {
-			continue
-		}
-		t := resolveABIAlias(s)
-		t.Attr |= s.Attr
-		t.SetExtname(s.Extname())
-		dynexp[i] = t
-	}
-
-	ctxt.cgo_export_static = nil
-	ctxt.cgo_export_dynamic = nil
-}
-
-// Set up flags and special symbols depending on the platform build mode.
-func (ctxt *Link) linksetup() {
-	switch ctxt.BuildMode {
-	case BuildModeCShared, BuildModePlugin:
-		s := ctxt.Syms.Lookup("runtime.islibrary", 0)
-		s.Type = sym.SNOPTRDATA
-		s.Attr |= sym.AttrDuplicateOK
-		s.AddUint8(1)
-	case BuildModeCArchive:
-		s := ctxt.Syms.Lookup("runtime.isarchive", 0)
-		s.Type = sym.SNOPTRDATA
-		s.Attr |= sym.AttrDuplicateOK
-		s.AddUint8(1)
-	}
-
-	// Recalculate pe parameters now that we have ctxt.LinkMode set.
-	if ctxt.HeadType == objabi.Hwindows {
-		Peinit(ctxt)
-	}
-
-	if ctxt.HeadType == objabi.Hdarwin && ctxt.LinkMode == LinkExternal {
-		*FlagTextAddr = 0
-	}
-
-	// If there are no dynamic libraries needed, gcc disables dynamic linking.
-	// Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13)
-	// assumes that a dynamic binary always refers to at least one dynamic library.
-	// Rather than be a source of test cases for glibc, disable dynamic linking
-	// the same way that gcc would.
-	//
-	// Exception: on OS X, programs such as Shark only work with dynamic
-	// binaries, so leave it enabled on OS X (Mach-O) binaries.
-	// Also leave it enabled on Solaris which doesn't support
-	// statically linked binaries.
-	if ctxt.BuildMode == BuildModeExe {
-		if havedynamic == 0 && ctxt.HeadType != objabi.Hdarwin && ctxt.HeadType != objabi.Hsolaris {
-			*FlagD = true
-		}
-	}
-
-	if ctxt.LinkMode == LinkExternal && ctxt.Arch.Family == sys.PPC64 && objabi.GOOS != "aix" {
-		toc := ctxt.Syms.Lookup(".TOC.", 0)
-		toc.Type = sym.SDYNIMPORT
-	}
-
-	// The Android Q linker started to complain about underalignment of the our TLS
-	// section. We don't actually use the section on android, so dont't
-	// generate it.
-	if objabi.GOOS != "android" {
-		tlsg := ctxt.Syms.Lookup("runtime.tlsg", 0)
-
-		// runtime.tlsg is used for external linking on platforms that do not define
-		// a variable to hold g in assembly (currently only intel).
-		if tlsg.Type == 0 {
-			tlsg.Type = sym.STLSBSS
-			tlsg.Size = int64(ctxt.Arch.PtrSize)
-		} else if tlsg.Type != sym.SDYNIMPORT {
-			Errorf(nil, "runtime declared tlsg variable %v", tlsg.Type)
-		}
-		tlsg.Attr |= sym.AttrReachable
-		ctxt.Tlsg = tlsg
-	}
-
-	var moduledata *sym.Symbol
-	if ctxt.BuildMode == BuildModePlugin {
-		moduledata = ctxt.Syms.Lookup("local.pluginmoduledata", 0)
-		moduledata.Attr |= sym.AttrLocal
-	} else {
-		moduledata = ctxt.Syms.Lookup("runtime.firstmoduledata", 0)
-	}
-	if moduledata.Type != 0 && moduledata.Type != sym.SDYNIMPORT {
-		// If the module (toolchain-speak for "executable or shared
-		// library") we are linking contains the runtime package, it
-		// will define the runtime.firstmoduledata symbol and we
-		// truncate it back to 0 bytes so we can define its entire
-		// contents in symtab.go:symtab().
-		moduledata.Size = 0
-
-		// In addition, on ARM, the runtime depends on the linker
-		// recording the value of GOARM.
-		if ctxt.Arch.Family == sys.ARM {
-			s := ctxt.Syms.Lookup("runtime.goarm", 0)
-			s.Type = sym.SDATA
-			s.Size = 0
-			s.AddUint8(uint8(objabi.GOARM))
-		}
-
-		if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
-			s := ctxt.Syms.Lookup("runtime.framepointer_enabled", 0)
-			s.Type = sym.SDATA
-			s.Size = 0
-			s.AddUint8(1)
-		}
-	} else {
-		// If OTOH the module does not contain the runtime package,
-		// create a local symbol for the moduledata.
-		moduledata = ctxt.Syms.Lookup("local.moduledata", 0)
-		moduledata.Attr |= sym.AttrLocal
-	}
-	// In all cases way we mark the moduledata as noptrdata to hide it from
-	// the GC.
-	moduledata.Type = sym.SNOPTRDATA
-	moduledata.Attr |= sym.AttrReachable
-	ctxt.Moduledata = moduledata
-
-	// If package versioning is required, generate a hash of the
-	// packages used in the link.
-	if ctxt.BuildMode == BuildModeShared || ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
-		for _, lib := range ctxt.Library {
-			if lib.Shlib == "" {
-				genhash(ctxt, lib)
-			}
-		}
-	}
-
-	if ctxt.Arch == sys.Arch386 && ctxt.HeadType != objabi.Hwindows {
-		if (ctxt.BuildMode == BuildModeCArchive && ctxt.IsELF) || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE || ctxt.DynlinkingGo() {
-			got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
-			got.Type = sym.SDYNIMPORT
-			got.Attr |= sym.AttrReachable
-		}
-	}
-}
-
-// mangleTypeSym shortens the names of symbols that represent Go types
-// if they are visible in the symbol table.
-//
-// As the names of these symbols are derived from the string of
-// the type, they can run to many kilobytes long. So we shorten
-// them using a SHA-1 when the name appears in the final binary.
-// This also removes characters that upset external linkers.
-//
-// These are the symbols that begin with the prefix 'type.' and
-// contain run-time type information used by the runtime and reflect
-// packages. All Go binaries contain these symbols, but only
-// those programs loaded dynamically in multiple parts need these
-// symbols to have entries in the symbol table.
-func (ctxt *Link) mangleTypeSym() {
-	if ctxt.BuildMode != BuildModeShared && !ctxt.linkShared && ctxt.BuildMode != BuildModePlugin && !ctxt.CanUsePlugins() {
-		return
-	}
-
-	for _, s := range ctxt.Syms.Allsym {
-		newName := typeSymbolMangle(s.Name)
-		if newName != s.Name {
-			ctxt.Syms.Rename(s.Name, newName, int(s.Version), ctxt.Reachparent)
-		}
-	}
-}
-
-// typeSymbolMangle mangles the given symbol name into something shorter.
-//
-// Keep the type.. prefix, which parts of the linker (like the
-// DWARF generator) know means the symbol is not decodable.
-// Leave type.runtime. symbols alone, because other parts of
-// the linker manipulates them.
-func typeSymbolMangle(name string) string {
-	if !strings.HasPrefix(name, "type.") {
-		return name
-	}
-	if strings.HasPrefix(name, "type.runtime.") {
-		return name
-	}
-	if len(name) <= 14 && !strings.Contains(name, "@") { // Issue 19529
-		return name
-	}
-	hash := sha1.Sum([]byte(name))
-	prefix := "type."
-	if name[5] == '.' {
-		prefix = "type.."
-	}
-	return prefix + base64.StdEncoding.EncodeToString(hash[:6])
-}
-
-/*
- * look for the next file in an archive.
- * adapted from libmach.
- */
-func nextar(bp *bio.Reader, off int64, a *ArHdr) int64 {
-	if off&1 != 0 {
-		off++
-	}
-	bp.MustSeek(off, 0)
-	var buf [SAR_HDR]byte
-	if n, err := io.ReadFull(bp, buf[:]); err != nil {
-		if n == 0 && err != io.EOF {
-			return -1
-		}
-		return 0
-	}
-
-	a.name = artrim(buf[0:16])
-	a.date = artrim(buf[16:28])
-	a.uid = artrim(buf[28:34])
-	a.gid = artrim(buf[34:40])
-	a.mode = artrim(buf[40:48])
-	a.size = artrim(buf[48:58])
-	a.fmag = artrim(buf[58:60])
-
-	arsize := atolwhex(a.size)
-	if arsize&1 != 0 {
-		arsize++
-	}
-	return arsize + SAR_HDR
-}
-
-func genhash(ctxt *Link, lib *sym.Library) {
-	f, err := bio.Open(lib.File)
-	if err != nil {
-		Errorf(nil, "cannot open file %s for hash generation: %v", lib.File, err)
-		return
-	}
-	defer f.Close()
-
-	var magbuf [len(ARMAG)]byte
-	if _, err := io.ReadFull(f, magbuf[:]); err != nil {
-		Exitf("file %s too short", lib.File)
-	}
-
-	if string(magbuf[:]) != ARMAG {
-		Exitf("%s is not an archive file", lib.File)
-	}
-
-	var arhdr ArHdr
-	l := nextar(f, f.Offset(), &arhdr)
-	if l <= 0 {
-		Errorf(nil, "%s: short read on archive file symbol header", lib.File)
-		return
-	}
-	if arhdr.name != pkgdef {
-		Errorf(nil, "%s: missing package data entry", lib.File)
-		return
-	}
-
-	h := sha1.New()
-
-	// To compute the hash of a package, we hash the first line of
-	// __.PKGDEF (which contains the toolchain version and any
-	// GOEXPERIMENT flags) and the export data (which is between
-	// the first two occurrences of "\n$$").
-
-	pkgDefBytes := make([]byte, atolwhex(arhdr.size))
-	_, err = io.ReadFull(f, pkgDefBytes)
-	if err != nil {
-		Errorf(nil, "%s: error reading package data: %v", lib.File, err)
-		return
-	}
-	firstEOL := bytes.IndexByte(pkgDefBytes, '\n')
-	if firstEOL < 0 {
-		Errorf(nil, "cannot parse package data of %s for hash generation, no newline found", lib.File)
-		return
-	}
-	firstDoubleDollar := bytes.Index(pkgDefBytes, []byte("\n$$"))
-	if firstDoubleDollar < 0 {
-		Errorf(nil, "cannot parse package data of %s for hash generation, no \\n$$ found", lib.File)
-		return
-	}
-	secondDoubleDollar := bytes.Index(pkgDefBytes[firstDoubleDollar+1:], []byte("\n$$"))
-	if secondDoubleDollar < 0 {
-		Errorf(nil, "cannot parse package data of %s for hash generation, only one \\n$$ found", lib.File)
-		return
-	}
-	h.Write(pkgDefBytes[0:firstEOL])
-	h.Write(pkgDefBytes[firstDoubleDollar : firstDoubleDollar+secondDoubleDollar])
-	lib.Hash = hex.EncodeToString(h.Sum(nil))
-}
-
-func loadobjfile(ctxt *Link, lib *sym.Library) {
-	pkg := objabi.PathToPrefix(lib.Pkg)
-
-	if ctxt.Debugvlog > 1 {
-		ctxt.Logf("ldobj: %s (%s)\n", lib.File, pkg)
-	}
-	f, err := bio.Open(lib.File)
-	if err != nil {
-		Exitf("cannot open file %s: %v", lib.File, err)
-	}
-	defer f.Close()
-	defer func() {
-		if pkg == "main" && !lib.Main {
-			Exitf("%s: not package main", lib.File)
-		}
-
-		// Ideally, we'd check that *all* object files within
-		// the archive were marked safe, but here we settle
-		// for *any*.
-		//
-		// Historically, cmd/link only checked the __.PKGDEF
-		// file, which in turn came from the first object
-		// file, typically produced by cmd/compile. The
-		// remaining object files are normally produced by
-		// cmd/asm, which doesn't support marking files as
-		// safe anyway. So at least in practice, this matches
-		// how safe mode has always worked.
-		if *flagU && !lib.Safe {
-			Exitf("%s: load of unsafe package %s", lib.File, pkg)
-		}
-	}()
-
-	for i := 0; i < len(ARMAG); i++ {
-		if c, err := f.ReadByte(); err == nil && c == ARMAG[i] {
-			continue
-		}
-
-		/* load it as a regular file */
-		l := f.MustSeek(0, 2)
-		f.MustSeek(0, 0)
-		ldobj(ctxt, f, lib, l, lib.File, lib.File)
-		return
-	}
-
-	/*
-	 * load all the object files from the archive now.
-	 * this gives us sequential file access and keeps us
-	 * from needing to come back later to pick up more
-	 * objects.  it breaks the usual C archive model, but
-	 * this is Go, not C.  the common case in Go is that
-	 * we need to load all the objects, and then we throw away
-	 * the individual symbols that are unused.
-	 *
-	 * loading every object will also make it possible to
-	 * load foreign objects not referenced by __.PKGDEF.
-	 */
-	var arhdr ArHdr
-	off := f.Offset()
-	for {
-		l := nextar(f, off, &arhdr)
-		if l == 0 {
-			break
-		}
-		if l < 0 {
-			Exitf("%s: malformed archive", lib.File)
-		}
-		off += l
-
-		// __.PKGDEF isn't a real Go object file, and it's
-		// absent in -linkobj builds anyway. Skipping it
-		// ensures consistency between -linkobj and normal
-		// build modes.
-		if arhdr.name == pkgdef {
-			continue
-		}
-
-		// Skip other special (non-object-file) sections that
-		// build tools may have added. Such sections must have
-		// short names so that the suffix is not truncated.
-		if len(arhdr.name) < 16 {
-			if ext := filepath.Ext(arhdr.name); ext != ".o" && ext != ".syso" {
-				continue
-			}
-		}
-
-		pname := fmt.Sprintf("%s(%s)", lib.File, arhdr.name)
-		l = atolwhex(arhdr.size)
-		ldobj(ctxt, f, lib, l, pname, lib.File)
-	}
-}
-
-type Hostobj struct {
-	ld     func(*Link, *bio.Reader, string, int64, string)
-	pkg    string
-	pn     string
-	file   string
-	off    int64
-	length int64
-}
-
-var hostobj []Hostobj
-
-// These packages can use internal linking mode.
-// Others trigger external mode.
-var internalpkg = []string{
-	"crypto/x509",
-	"net",
-	"os/user",
-	"runtime/cgo",
-	"runtime/race",
-	"runtime/msan",
-}
-
-func ldhostobj(ld func(*Link, *bio.Reader, string, int64, string), headType objabi.HeadType, f *bio.Reader, pkg string, length int64, pn string, file string) *Hostobj {
-	isinternal := false
-	for _, intpkg := range internalpkg {
-		if pkg == intpkg {
-			isinternal = true
-			break
-		}
-	}
-
-	// DragonFly declares errno with __thread, which results in a symbol
-	// type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not
-	// currently know how to handle TLS relocations, hence we have to
-	// force external linking for any libraries that link in code that
-	// uses errno. This can be removed if the Go linker ever supports
-	// these relocation types.
-	if headType == objabi.Hdragonfly {
-		if pkg == "net" || pkg == "os/user" {
-			isinternal = false
-		}
-	}
-
-	if !isinternal {
-		externalobj = true
-	}
-
-	hostobj = append(hostobj, Hostobj{})
-	h := &hostobj[len(hostobj)-1]
-	h.ld = ld
-	h.pkg = pkg
-	h.pn = pn
-	h.file = file
-	h.off = f.Offset()
-	h.length = length
-	return h
-}
-
-func hostobjs(ctxt *Link) {
-	if ctxt.LinkMode != LinkInternal {
-		return
-	}
-	var h *Hostobj
-
-	for i := 0; i < len(hostobj); i++ {
-		h = &hostobj[i]
-		f, err := bio.Open(h.file)
-		if err != nil {
-			Exitf("cannot reopen %s: %v", h.pn, err)
-		}
-
-		f.MustSeek(h.off, 0)
-		h.ld(ctxt, f, h.pkg, h.length, h.pn)
-		f.Close()
-	}
-}
-
-func hostlinksetup(ctxt *Link) {
-	if ctxt.LinkMode != LinkExternal {
-		return
-	}
-
-	// For external link, record that we need to tell the external linker -s,
-	// and turn off -s internally: the external linker needs the symbol
-	// information for its final link.
-	debug_s = *FlagS
-	*FlagS = false
-
-	// create temporary directory and arrange cleanup
-	if *flagTmpdir == "" {
-		dir, err := ioutil.TempDir("", "go-link-")
-		if err != nil {
-			log.Fatal(err)
-		}
-		*flagTmpdir = dir
-		ownTmpDir = true
-		AtExit(func() {
-			ctxt.Out.f.Close()
-			os.RemoveAll(*flagTmpdir)
-		})
-	}
-
-	// change our output to temporary object file
-	ctxt.Out.f.Close()
-	mayberemoveoutfile()
-
-	p := filepath.Join(*flagTmpdir, "go.o")
-	var err error
-	f, err := os.OpenFile(p, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775)
-	if err != nil {
-		Exitf("cannot create %s: %v", p, err)
-	}
-
-	ctxt.Out.w = bufio.NewWriter(f)
-	ctxt.Out.f = f
-	ctxt.Out.off = 0
-}
-
-// hostobjCopy creates a copy of the object files in hostobj in a
-// temporary directory.
-func hostobjCopy() (paths []string) {
-	var wg sync.WaitGroup
-	sema := make(chan struct{}, runtime.NumCPU()) // limit open file descriptors
-	for i, h := range hostobj {
-		h := h
-		dst := filepath.Join(*flagTmpdir, fmt.Sprintf("%06d.o", i))
-		paths = append(paths, dst)
-
-		wg.Add(1)
-		go func() {
-			sema <- struct{}{}
-			defer func() {
-				<-sema
-				wg.Done()
-			}()
-			f, err := os.Open(h.file)
-			if err != nil {
-				Exitf("cannot reopen %s: %v", h.pn, err)
-			}
-			defer f.Close()
-			if _, err := f.Seek(h.off, 0); err != nil {
-				Exitf("cannot seek %s: %v", h.pn, err)
-			}
-
-			w, err := os.Create(dst)
-			if err != nil {
-				Exitf("cannot create %s: %v", dst, err)
-			}
-			if _, err := io.CopyN(w, f, h.length); err != nil {
-				Exitf("cannot write %s: %v", dst, err)
-			}
-			if err := w.Close(); err != nil {
-				Exitf("cannot close %s: %v", dst, err)
-			}
-		}()
-	}
-	wg.Wait()
-	return paths
-}
-
-// writeGDBLinkerScript creates gcc linker script file in temp
-// directory. writeGDBLinkerScript returns created file path.
-// The script is used to work around gcc bug
-// (see https://golang.org/issue/20183 for details).
-func writeGDBLinkerScript() string {
-	name := "fix_debug_gdb_scripts.ld"
-	path := filepath.Join(*flagTmpdir, name)
-	src := `SECTIONS
-{
-  .debug_gdb_scripts BLOCK(__section_alignment__) (NOLOAD) :
-  {
-    *(.debug_gdb_scripts)
-  }
-}
-INSERT AFTER .debug_types;
-`
-	err := ioutil.WriteFile(path, []byte(src), 0666)
-	if err != nil {
-		Errorf(nil, "WriteFile %s failed: %v", name, err)
-	}
-	return path
-}
-
-// archive builds a .a archive from the hostobj object files.
-func (ctxt *Link) archive() {
-	if ctxt.BuildMode != BuildModeCArchive {
-		return
-	}
-
-	exitIfErrors()
-
-	if *flagExtar == "" {
-		*flagExtar = "ar"
-	}
-
-	mayberemoveoutfile()
-
-	// Force the buffer to flush here so that external
-	// tools will see a complete file.
-	ctxt.Out.Flush()
-	if err := ctxt.Out.f.Close(); err != nil {
-		Exitf("close: %v", err)
-	}
-	ctxt.Out.f = nil
-
-	argv := []string{*flagExtar, "-q", "-c", "-s"}
-	if ctxt.HeadType == objabi.Haix {
-		argv = append(argv, "-X64")
-	}
-	argv = append(argv, *flagOutfile)
-	argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
-	argv = append(argv, hostobjCopy()...)
-
-	if ctxt.Debugvlog != 0 {
-		ctxt.Logf("archive: %s\n", strings.Join(argv, " "))
-	}
-
-	// If supported, use syscall.Exec() to invoke the archive command,
-	// which should be the final remaining step needed for the link.
-	// This will reduce peak RSS for the link (and speed up linking of
-	// large applications), since when the archive command runs we
-	// won't be holding onto all of the linker's live memory.
-	if syscallExecSupported && !ownTmpDir {
-		runAtExitFuncs()
-		ctxt.execArchive(argv)
-		panic("should not get here")
-	}
-
-	// Otherwise invoke 'ar' in the usual way (fork + exec).
-	if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
-		Exitf("running %s failed: %v\n%s", argv[0], err, out)
-	}
-}
-
-func (ctxt *Link) hostlink() {
-	if ctxt.LinkMode != LinkExternal || nerrors > 0 {
-		return
-	}
-	if ctxt.BuildMode == BuildModeCArchive {
-		return
-	}
-
-	var argv []string
-	argv = append(argv, ctxt.extld())
-	argv = append(argv, hostlinkArchArgs(ctxt.Arch)...)
-
-	if *FlagS || debug_s {
-		if ctxt.HeadType == objabi.Hdarwin {
-			// Recent versions of macOS print
-			//	ld: warning: option -s is obsolete and being ignored
-			// so do not pass any arguments.
-		} else {
-			argv = append(argv, "-s")
-		}
-	}
-
-	switch ctxt.HeadType {
-	case objabi.Hdarwin:
-		if machoPlatform == PLATFORM_MACOS {
-			// -headerpad is incompatible with -fembed-bitcode.
-			argv = append(argv, "-Wl,-headerpad,1144")
-		}
-		if ctxt.DynlinkingGo() && !ctxt.Arch.InFamily(sys.ARM, sys.ARM64) {
-			argv = append(argv, "-Wl,-flat_namespace")
-		}
-	case objabi.Hopenbsd:
-		argv = append(argv, "-Wl,-nopie")
-	case objabi.Hwindows:
-		if windowsgui {
-			argv = append(argv, "-mwindows")
-		} else {
-			argv = append(argv, "-mconsole")
-		}
-		// Mark as having awareness of terminal services, to avoid
-		// ancient compatibility hacks.
-		argv = append(argv, "-Wl,--tsaware")
-
-		// Enable DEP
-		argv = append(argv, "-Wl,--nxcompat")
-
-		argv = append(argv, fmt.Sprintf("-Wl,--major-os-version=%d", PeMinimumTargetMajorVersion))
-		argv = append(argv, fmt.Sprintf("-Wl,--minor-os-version=%d", PeMinimumTargetMinorVersion))
-		argv = append(argv, fmt.Sprintf("-Wl,--major-subsystem-version=%d", PeMinimumTargetMajorVersion))
-		argv = append(argv, fmt.Sprintf("-Wl,--minor-subsystem-version=%d", PeMinimumTargetMinorVersion))
-	case objabi.Haix:
-		argv = append(argv, "-pthread")
-		// prevent ld to reorder .text functions to keep the same
-		// first/last functions for moduledata.
-		argv = append(argv, "-Wl,-bnoobjreorder")
-		// mcmodel=large is needed for every gcc generated files, but
-		// ld still need -bbigtoc in order to allow larger TOC.
-		argv = append(argv, "-mcmodel=large")
-		argv = append(argv, "-Wl,-bbigtoc")
-	}
-
-	switch ctxt.BuildMode {
-	case BuildModeExe:
-		if ctxt.HeadType == objabi.Hdarwin {
-			if machoPlatform == PLATFORM_MACOS {
-				argv = append(argv, "-Wl,-no_pie")
-				argv = append(argv, "-Wl,-pagezero_size,4000000")
-			}
-		}
-	case BuildModePIE:
-		switch ctxt.HeadType {
-		case objabi.Hdarwin, objabi.Haix:
-		case objabi.Hwindows:
-			// Enable ASLR.
-			argv = append(argv, "-Wl,--dynamicbase")
-			// enable high-entropy ASLR on 64-bit.
-			if ctxt.Arch.PtrSize >= 8 {
-				argv = append(argv, "-Wl,--high-entropy-va")
-			}
-			// Work around binutils limitation that strips relocation table for dynamicbase.
-			// See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
-			argv = append(argv, "-Wl,--export-all-symbols")
-		default:
-			// ELF.
-			if ctxt.UseRelro() {
-				argv = append(argv, "-Wl,-z,relro")
-			}
-			argv = append(argv, "-pie")
-		}
-	case BuildModeCShared:
-		if ctxt.HeadType == objabi.Hdarwin {
-			argv = append(argv, "-dynamiclib")
-			if ctxt.Arch.Family != sys.AMD64 {
-				argv = append(argv, "-Wl,-read_only_relocs,suppress")
-			}
-		} else {
-			// ELF.
-			argv = append(argv, "-Wl,-Bsymbolic")
-			if ctxt.UseRelro() {
-				argv = append(argv, "-Wl,-z,relro")
-			}
-			argv = append(argv, "-shared")
-			if ctxt.HeadType != objabi.Hwindows {
-				// Pass -z nodelete to mark the shared library as
-				// non-closeable: a dlclose will do nothing.
-				argv = append(argv, "-Wl,-z,nodelete")
-			}
-		}
-	case BuildModeShared:
-		if ctxt.UseRelro() {
-			argv = append(argv, "-Wl,-z,relro")
-		}
-		argv = append(argv, "-shared")
-	case BuildModePlugin:
-		if ctxt.HeadType == objabi.Hdarwin {
-			argv = append(argv, "-dynamiclib")
-		} else {
-			if ctxt.UseRelro() {
-				argv = append(argv, "-Wl,-z,relro")
-			}
-			argv = append(argv, "-shared")
-		}
-	}
-
-	if ctxt.IsELF && ctxt.DynlinkingGo() {
-		// We force all symbol resolution to be done at program startup
-		// because lazy PLT resolution can use large amounts of stack at
-		// times we cannot allow it to do so.
-		argv = append(argv, "-Wl,-znow")
-
-		// Do not let the host linker generate COPY relocations. These
-		// can move symbols out of sections that rely on stable offsets
-		// from the beginning of the section (like sym.STYPE).
-		argv = append(argv, "-Wl,-znocopyreloc")
-
-		if ctxt.Arch.InFamily(sys.ARM, sys.ARM64) && objabi.GOOS == "linux" {
-			// On ARM, the GNU linker will generate COPY relocations
-			// even with -znocopyreloc set.
-			// https://sourceware.org/bugzilla/show_bug.cgi?id=19962
-			//
-			// On ARM64, the GNU linker will fail instead of
-			// generating COPY relocations.
-			//
-			// In both cases, switch to gold.
-			argv = append(argv, "-fuse-ld=gold")
-
-			// If gold is not installed, gcc will silently switch
-			// back to ld.bfd. So we parse the version information
-			// and provide a useful error if gold is missing.
-			cmd := exec.Command(*flagExtld, "-fuse-ld=gold", "-Wl,--version")
-			if out, err := cmd.CombinedOutput(); err == nil {
-				if !bytes.Contains(out, []byte("GNU gold")) {
-					log.Fatalf("ARM external linker must be gold (issue #15696), but is not: %s", out)
-				}
-			}
-		}
-	}
-
-	if ctxt.Arch.Family == sys.ARM64 && objabi.GOOS == "freebsd" {
-		// Switch to ld.bfd on freebsd/arm64.
-		argv = append(argv, "-fuse-ld=bfd")
-
-		// Provide a useful error if ld.bfd is missing.
-		cmd := exec.Command(*flagExtld, "-fuse-ld=bfd", "-Wl,--version")
-		if out, err := cmd.CombinedOutput(); err == nil {
-			if !bytes.Contains(out, []byte("GNU ld")) {
-				log.Fatalf("ARM64 external linker must be ld.bfd (issue #35197), please install devel/binutils")
-			}
-		}
-	}
-
-	if ctxt.IsELF && len(buildinfo) > 0 {
-		argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo))
-	}
-
-	// On Windows, given -o foo, GCC will append ".exe" to produce
-	// "foo.exe".  We have decided that we want to honor the -o
-	// option. To make this work, we append a '.' so that GCC
-	// will decide that the file already has an extension. We
-	// only want to do this when producing a Windows output file
-	// on a Windows host.
-	outopt := *flagOutfile
-	if objabi.GOOS == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" {
-		outopt += "."
-	}
-	argv = append(argv, "-o")
-	argv = append(argv, outopt)
-
-	if rpath.val != "" {
-		argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val))
-	}
-
-	// Force global symbols to be exported for dlopen, etc.
-	if ctxt.IsELF {
-		argv = append(argv, "-rdynamic")
-	}
-	if ctxt.HeadType == objabi.Haix {
-		fileName := xcoffCreateExportFile(ctxt)
-		argv = append(argv, "-Wl,-bE:"+fileName)
-	}
-
-	if strings.Contains(argv[0], "clang") {
-		argv = append(argv, "-Qunused-arguments")
-	}
-
-	const compressDWARF = "-Wl,--compress-debug-sections=zlib-gnu"
-	if ctxt.compressDWARF && linkerFlagSupported(argv[0], compressDWARF) {
-		argv = append(argv, compressDWARF)
-	}
-
-	argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
-	argv = append(argv, hostobjCopy()...)
-	if ctxt.HeadType == objabi.Haix {
-		// We want to have C files after Go files to remove
-		// trampolines csects made by ld.
-		argv = append(argv, "-nostartfiles")
-		argv = append(argv, "/lib/crt0_64.o")
-
-		extld := ctxt.extld()
-		// Get starting files.
-		getPathFile := func(file string) string {
-			args := []string{"-maix64", "--print-file-name=" + file}
-			out, err := exec.Command(extld, args...).CombinedOutput()
-			if err != nil {
-				log.Fatalf("running %s failed: %v\n%s", extld, err, out)
-			}
-			return strings.Trim(string(out), "\n")
-		}
-		argv = append(argv, getPathFile("crtcxa.o"))
-		argv = append(argv, getPathFile("crtdbase.o"))
-	}
-
-	if ctxt.linkShared {
-		seenDirs := make(map[string]bool)
-		seenLibs := make(map[string]bool)
-		addshlib := func(path string) {
-			dir, base := filepath.Split(path)
-			if !seenDirs[dir] {
-				argv = append(argv, "-L"+dir)
-				if !rpath.set {
-					argv = append(argv, "-Wl,-rpath="+dir)
-				}
-				seenDirs[dir] = true
-			}
-			base = strings.TrimSuffix(base, ".so")
-			base = strings.TrimPrefix(base, "lib")
-			if !seenLibs[base] {
-				argv = append(argv, "-l"+base)
-				seenLibs[base] = true
-			}
-		}
-		for _, shlib := range ctxt.Shlibs {
-			addshlib(shlib.Path)
-			for _, dep := range shlib.Deps {
-				if dep == "" {
-					continue
-				}
-				libpath := findshlib(ctxt, dep)
-				if libpath != "" {
-					addshlib(libpath)
-				}
-			}
-		}
-	}
-
-	// clang, unlike GCC, passes -rdynamic to the linker
-	// even when linking with -static, causing a linker
-	// error when using GNU ld. So take out -rdynamic if
-	// we added it. We do it in this order, rather than
-	// only adding -rdynamic later, so that -*extldflags
-	// can override -rdynamic without using -static.
-	checkStatic := func(arg string) {
-		if ctxt.IsELF && arg == "-static" {
-			for i := range argv {
-				if argv[i] == "-rdynamic" {
-					argv[i] = "-static"
-				}
-			}
-		}
-	}
-
-	for _, p := range ldflag {
-		argv = append(argv, p)
-		checkStatic(p)
-	}
-
-	// When building a program with the default -buildmode=exe the
-	// gc compiler generates code requires DT_TEXTREL in a
-	// position independent executable (PIE). On systems where the
-	// toolchain creates PIEs by default, and where DT_TEXTREL
-	// does not work, the resulting programs will not run. See
-	// issue #17847. To avoid this problem pass -no-pie to the
-	// toolchain if it is supported.
-	if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared {
-		// GCC uses -no-pie, clang uses -nopie.
-		for _, nopie := range []string{"-no-pie", "-nopie"} {
-			if linkerFlagSupported(argv[0], nopie) {
-				argv = append(argv, nopie)
-				break
-			}
-		}
-	}
-
-	for _, p := range strings.Fields(*flagExtldflags) {
-		argv = append(argv, p)
-		checkStatic(p)
-	}
-	if ctxt.HeadType == objabi.Hwindows {
-		// use gcc linker script to work around gcc bug
-		// (see https://golang.org/issue/20183 for details).
-		p := writeGDBLinkerScript()
-		argv = append(argv, "-Wl,-T,"+p)
-		// libmingw32 and libmingwex have some inter-dependencies,
-		// so must use linker groups.
-		argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group")
-		argv = append(argv, peimporteddlls()...)
-	}
-
-	if ctxt.Debugvlog != 0 {
-		ctxt.Logf("host link:")
-		for _, v := range argv {
-			ctxt.Logf(" %q", v)
-		}
-		ctxt.Logf("\n")
-	}
-
-	out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput()
-	if err != nil {
-		Exitf("running %s failed: %v\n%s", argv[0], err, out)
-	}
-
-	// Filter out useless linker warnings caused by bugs outside Go.
-	// See also cmd/go/internal/work/exec.go's gccld method.
-	var save [][]byte
-	var skipLines int
-	for _, line := range bytes.SplitAfter(out, []byte("\n")) {
-		// golang.org/issue/26073 - Apple Xcode bug
-		if bytes.Contains(line, []byte("ld: warning: text-based stub file")) {
-			continue
-		}
-
-		if skipLines > 0 {
-			skipLines--
-			continue
-		}
-
-		// Remove TOC overflow warning on AIX.
-		if bytes.Contains(line, []byte("ld: 0711-783")) {
-			skipLines = 2
-			continue
-		}
-
-		save = append(save, line)
-	}
-	out = bytes.Join(save, nil)
-
-	if len(out) > 0 {
-		// always print external output even if the command is successful, so that we don't
-		// swallow linker warnings (see https://golang.org/issue/17935).
-		ctxt.Logf("%s", out)
-	}
-
-	if !*FlagS && !*FlagW && !debug_s && ctxt.HeadType == objabi.Hdarwin {
-		dsym := filepath.Join(*flagTmpdir, "go.dwarf")
-		if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
-			Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
-		}
-		// Skip combining if `dsymutil` didn't generate a file. See #11994.
-		if _, err := os.Stat(dsym); os.IsNotExist(err) {
-			return
-		}
-		// For os.Rename to work reliably, must be in same directory as outfile.
-		combinedOutput := *flagOutfile + "~"
-		exef, err := os.Open(*flagOutfile)
-		if err != nil {
-			Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
-		}
-		defer exef.Close()
-		exem, err := macho.NewFile(exef)
-		if err != nil {
-			Exitf("%s: parsing Mach-O header failed: %v", os.Args[0], err)
-		}
-		// Only macOS supports unmapped segments such as our __DWARF segment.
-		if machoPlatform == PLATFORM_MACOS {
-			if err := machoCombineDwarf(ctxt, exef, exem, dsym, combinedOutput); err != nil {
-				Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
-			}
-			os.Remove(*flagOutfile)
-			if err := os.Rename(combinedOutput, *flagOutfile); err != nil {
-				Exitf("%s: %v", os.Args[0], err)
-			}
-		}
-	}
-}
-
-var createTrivialCOnce sync.Once
-
-func linkerFlagSupported(linker, flag string) bool {
-	createTrivialCOnce.Do(func() {
-		src := filepath.Join(*flagTmpdir, "trivial.c")
-		if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil {
-			Errorf(nil, "WriteFile trivial.c failed: %v", err)
-		}
-	})
-
-	flagsWithNextArgSkip := []string{
-		"-F",
-		"-l",
-		"-L",
-		"-framework",
-		"-Wl,-framework",
-		"-Wl,-rpath",
-		"-Wl,-undefined",
-	}
-	flagsWithNextArgKeep := []string{
-		"-arch",
-		"-isysroot",
-		"--sysroot",
-		"-target",
-	}
-	prefixesToKeep := []string{
-		"-f",
-		"-m",
-		"-p",
-		"-Wl,",
-		"-arch",
-		"-isysroot",
-		"--sysroot",
-		"-target",
-	}
-
-	var flags []string
-	keep := false
-	skip := false
-	extldflags := strings.Fields(*flagExtldflags)
-	for _, f := range append(extldflags, ldflag...) {
-		if keep {
-			flags = append(flags, f)
-			keep = false
-		} else if skip {
-			skip = false
-		} else if f == "" || f[0] != '-' {
-		} else if contains(flagsWithNextArgSkip, f) {
-			skip = true
-		} else if contains(flagsWithNextArgKeep, f) {
-			flags = append(flags, f)
-			keep = true
-		} else {
-			for _, p := range prefixesToKeep {
-				if strings.HasPrefix(f, p) {
-					flags = append(flags, f)
-					break
-				}
-			}
-		}
-	}
-
-	flags = append(flags, flag, "trivial.c")
-
-	cmd := exec.Command(linker, flags...)
-	cmd.Dir = *flagTmpdir
-	cmd.Env = append([]string{"LC_ALL=C"}, os.Environ()...)
-	out, err := cmd.CombinedOutput()
-	// GCC says "unrecognized command line option ‘-no-pie’"
-	// clang says "unknown argument: '-no-pie'"
-	return err == nil && !bytes.Contains(out, []byte("unrecognized")) && !bytes.Contains(out, []byte("unknown"))
-}
-
-// hostlinkArchArgs returns arguments to pass to the external linker
-// based on the architecture.
-func hostlinkArchArgs(arch *sys.Arch) []string {
-	switch arch.Family {
-	case sys.I386:
-		return []string{"-m32"}
-	case sys.AMD64, sys.S390X:
-		return []string{"-m64"}
-	case sys.ARM:
-		return []string{"-marm"}
-	case sys.ARM64:
-		// nothing needed
-	case sys.MIPS64:
-		return []string{"-mabi=64"}
-	case sys.MIPS:
-		return []string{"-mabi=32"}
-	case sys.PPC64:
-		if objabi.GOOS == "aix" {
-			return []string{"-maix64"}
-		} else {
-			return []string{"-m64"}
-		}
-
-	}
-	return nil
-}
-
-// ldobj loads an input object. If it is a host object (an object
-// compiled by a non-Go compiler) it returns the Hostobj pointer. If
-// it is a Go object, it returns nil.
-func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, file string) *Hostobj {
-	pkg := objabi.PathToPrefix(lib.Pkg)
-
-	eof := f.Offset() + length
-	start := f.Offset()
-	c1 := bgetc(f)
-	c2 := bgetc(f)
-	c3 := bgetc(f)
-	c4 := bgetc(f)
-	f.MustSeek(start, 0)
-
-	unit := &sym.CompilationUnit{Lib: lib}
-	lib.Units = append(lib.Units, unit)
-
-	magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
-	if magic == 0x7f454c46 { // \x7F E L F
-		if *flagNewobj {
-			ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-				textp, flags, err := loadelf.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn, ehdr.flags)
-				if err != nil {
-					Errorf(nil, "%v", err)
-					return
-				}
-				ehdr.flags = flags
-				ctxt.Textp = append(ctxt.Textp, textp...)
-			}
-			return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file)
-		} else {
-			ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-				textp, flags, err := loadelf.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn, ehdr.flags)
-				if err != nil {
-					Errorf(nil, "%v", err)
-					return
-				}
-				ehdr.flags = flags
-				ctxt.Textp = append(ctxt.Textp, textp...)
-			}
-			return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file)
-		}
-	}
-
-	if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe {
-		if *flagNewobj {
-			ldmacho := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-				textp, err := loadmacho.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
-				if err != nil {
-					Errorf(nil, "%v", err)
-					return
-				}
-				ctxt.Textp = append(ctxt.Textp, textp...)
-			}
-			return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
-		} else {
-			ldmacho := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-				textp, err := loadmacho.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
-				if err != nil {
-					Errorf(nil, "%v", err)
-					return
-				}
-				ctxt.Textp = append(ctxt.Textp, textp...)
-			}
-			return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
-		}
-	}
-
-	if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 {
-		if *flagNewobj {
-			ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-				textp, rsrc, err := loadpe.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
-				if err != nil {
-					Errorf(nil, "%v", err)
-					return
-				}
-				if rsrc != nil {
-					setpersrc(ctxt, rsrc)
-				}
-				ctxt.Textp = append(ctxt.Textp, textp...)
-			}
-			return ldhostobj(ldpe, ctxt.HeadType, f, pkg, length, pn, file)
-		} else {
-			ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-				textp, rsrc, err := loadpe.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
-				if err != nil {
-					Errorf(nil, "%v", err)
-					return
-				}
-				if rsrc != nil {
-					setpersrc(ctxt, rsrc)
-				}
-				ctxt.Textp = append(ctxt.Textp, textp...)
-			}
-			return ldhostobj(ldpe, ctxt.HeadType, f, pkg, length, pn, file)
-		}
-	}
-
-	if c1 == 0x01 && (c2 == 0xD7 || c2 == 0xF7) {
-		if *flagNewobj {
-			ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-				textp, err := loadxcoff.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
-				if err != nil {
-					Errorf(nil, "%v", err)
-					return
-				}
-				ctxt.Textp = append(ctxt.Textp, textp...)
-			}
-			return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file)
-		} else {
-			ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-				textp, err := loadxcoff.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
-				if err != nil {
-					Errorf(nil, "%v", err)
-					return
-				}
-				ctxt.Textp = append(ctxt.Textp, textp...)
-			}
-			return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file)
-		}
-	}
-
-	/* check the header */
-	line, err := f.ReadString('\n')
-	if err != nil {
-		Errorf(nil, "truncated object file: %s: %v", pn, err)
-		return nil
-	}
-
-	if !strings.HasPrefix(line, "go object ") {
-		if strings.HasSuffix(pn, ".go") {
-			Exitf("%s: uncompiled .go source file", pn)
-			return nil
-		}
-
-		if line == ctxt.Arch.Name {
-			// old header format: just $GOOS
-			Errorf(nil, "%s: stale object file", pn)
-			return nil
-		}
-
-		Errorf(nil, "%s: not an object file", pn)
-		return nil
-	}
-
-	// First, check that the basic GOOS, GOARCH, and Version match.
-	t := fmt.Sprintf("%s %s %s ", objabi.GOOS, objabi.GOARCH, objabi.Version)
-
-	line = strings.TrimRight(line, "\n")
-	if !strings.HasPrefix(line[10:]+" ", t) && !*flagF {
-		Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], t)
-		return nil
-	}
-
-	// Second, check that longer lines match each other exactly,
-	// so that the Go compiler and write additional information
-	// that must be the same from run to run.
-	if len(line) >= len(t)+10 {
-		if theline == "" {
-			theline = line[10:]
-		} else if theline != line[10:] {
-			Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], theline)
-			return nil
-		}
-	}
-
-	// Skip over exports and other info -- ends with \n!\n.
-	//
-	// Note: It's possible for "\n!\n" to appear within the binary
-	// package export data format. To avoid truncating the package
-	// definition prematurely (issue 21703), we keep track of
-	// how many "$$" delimiters we've seen.
-
-	import0 := f.Offset()
-
-	c1 = '\n' // the last line ended in \n
-	c2 = bgetc(f)
-	c3 = bgetc(f)
-	markers := 0
-	for {
-		if c1 == '\n' {
-			if markers%2 == 0 && c2 == '!' && c3 == '\n' {
-				break
-			}
-			if c2 == '$' && c3 == '$' {
-				markers++
-			}
-		}
-
-		c1 = c2
-		c2 = c3
-		c3 = bgetc(f)
-		if c3 == -1 {
-			Errorf(nil, "truncated object file: %s", pn)
-			return nil
-		}
-	}
-
-	import1 := f.Offset()
-
-	f.MustSeek(import0, 0)
-	ldpkg(ctxt, f, lib, import1-import0-2, pn) // -2 for !\n
-	f.MustSeek(import1, 0)
-
-	flags := 0
-	switch *FlagStrictDups {
-	case 0:
-		break
-	case 1:
-		flags = objfile.StrictDupsWarnFlag
-	case 2:
-		flags = objfile.StrictDupsErrFlag
-	default:
-		log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups)
-	}
-	var c int
-	if *flagNewobj {
-		ctxt.loader.Preload(ctxt.Arch, ctxt.Syms, f, lib, unit, eof-f.Offset(), pn, flags)
-	} else {
-		c = objfile.Load(ctxt.Arch, ctxt.Syms, f, lib, unit, eof-f.Offset(), pn, flags)
-	}
-	strictDupMsgCount += c
-	addImports(ctxt, lib, pn)
-	return nil
-}
-
-func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte {
-	data := make([]byte, sym.Size)
-	sect := f.Sections[sym.Section]
-	if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE {
-		Errorf(nil, "reading %s from non-data section", sym.Name)
-	}
-	n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr))
-	if uint64(n) != sym.Size {
-		Errorf(nil, "reading contents of %s: %v", sym.Name, err)
-	}
-	return data
-}
-
-func readwithpad(r io.Reader, sz int32) ([]byte, error) {
-	data := make([]byte, Rnd(int64(sz), 4))
-	_, err := io.ReadFull(r, data)
-	if err != nil {
-		return nil, err
-	}
-	data = data[:sz]
-	return data, nil
-}
-
-func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) {
-	for _, sect := range f.Sections {
-		if sect.Type != elf.SHT_NOTE {
-			continue
-		}
-		r := sect.Open()
-		for {
-			var namesize, descsize, noteType int32
-			err := binary.Read(r, f.ByteOrder, &namesize)
-			if err != nil {
-				if err == io.EOF {
-					break
-				}
-				return nil, fmt.Errorf("read namesize failed: %v", err)
-			}
-			err = binary.Read(r, f.ByteOrder, &descsize)
-			if err != nil {
-				return nil, fmt.Errorf("read descsize failed: %v", err)
-			}
-			err = binary.Read(r, f.ByteOrder, &noteType)
-			if err != nil {
-				return nil, fmt.Errorf("read type failed: %v", err)
-			}
-			noteName, err := readwithpad(r, namesize)
-			if err != nil {
-				return nil, fmt.Errorf("read name failed: %v", err)
-			}
-			desc, err := readwithpad(r, descsize)
-			if err != nil {
-				return nil, fmt.Errorf("read desc failed: %v", err)
-			}
-			if string(name) == string(noteName) && typ == noteType {
-				return desc, nil
-			}
-		}
-	}
-	return nil, nil
-}
-
-func findshlib(ctxt *Link, shlib string) string {
-	if filepath.IsAbs(shlib) {
-		return shlib
-	}
-	for _, libdir := range ctxt.Libdir {
-		libpath := filepath.Join(libdir, shlib)
-		if _, err := os.Stat(libpath); err == nil {
-			return libpath
-		}
-	}
-	Errorf(nil, "cannot find shared library: %s", shlib)
-	return ""
-}
-
-func ldshlibsyms(ctxt *Link, shlib string) {
-	var libpath string
-	if filepath.IsAbs(shlib) {
-		libpath = shlib
-		shlib = filepath.Base(shlib)
-	} else {
-		libpath = findshlib(ctxt, shlib)
-		if libpath == "" {
-			return
-		}
-	}
-	for _, processedlib := range ctxt.Shlibs {
-		if processedlib.Path == libpath {
-			return
-		}
-	}
-	if ctxt.Debugvlog > 1 {
-		ctxt.Logf("ldshlibsyms: found library with name %s at %s\n", shlib, libpath)
-	}
-
-	f, err := elf.Open(libpath)
-	if err != nil {
-		Errorf(nil, "cannot open shared library: %s", libpath)
-		return
-	}
-	defer f.Close()
-
-	hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG)
-	if err != nil {
-		Errorf(nil, "cannot read ABI hash from shared library %s: %v", libpath, err)
-		return
-	}
-
-	depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG)
-	if err != nil {
-		Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err)
-		return
-	}
-	var deps []string
-	for _, dep := range strings.Split(string(depsbytes), "\n") {
-		if dep == "" {
-			continue
-		}
-		if !filepath.IsAbs(dep) {
-			// If the dep can be interpreted as a path relative to the shlib
-			// in which it was found, do that. Otherwise, we will leave it
-			// to be resolved by libdir lookup.
-			abs := filepath.Join(filepath.Dir(libpath), dep)
-			if _, err := os.Stat(abs); err == nil {
-				dep = abs
-			}
-		}
-		deps = append(deps, dep)
-	}
-
-	syms, err := f.DynamicSymbols()
-	if err != nil {
-		Errorf(nil, "cannot read symbols from shared library: %s", libpath)
-		return
-	}
-	gcdataLocations := make(map[uint64]*sym.Symbol)
-	for _, elfsym := range syms {
-		if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
-			continue
-		}
-
-		// Symbols whose names start with "type." are compiler
-		// generated, so make functions with that prefix internal.
-		ver := 0
-		if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type.") {
-			ver = sym.SymVerABIInternal
-		}
-
-		var lsym *sym.Symbol
-		if *flagNewobj {
-			i := ctxt.loader.AddExtSym(elfsym.Name, ver)
-			if i == 0 {
-				continue
-			}
-			lsym = ctxt.Syms.Newsym(elfsym.Name, ver)
-			ctxt.loader.Syms[i] = lsym
-		} else {
-			lsym = ctxt.Syms.Lookup(elfsym.Name, ver)
-		}
-		// Because loadlib above loads all .a files before loading any shared
-		// libraries, any non-dynimport symbols we find that duplicate symbols
-		// already loaded should be ignored (the symbols from the .a files
-		// "win").
-		if lsym.Type != 0 && lsym.Type != sym.SDYNIMPORT {
-			continue
-		}
-		lsym.Type = sym.SDYNIMPORT
-		lsym.SetElfType(elf.ST_TYPE(elfsym.Info))
-		lsym.Size = int64(elfsym.Size)
-		if elfsym.Section != elf.SHN_UNDEF {
-			// Set .File for the library that actually defines the symbol.
-			lsym.File = libpath
-			// The decodetype_* functions in decodetype.go need access to
-			// the type data.
-			if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") {
-				lsym.P = readelfsymboldata(ctxt, f, &elfsym)
-				gcdataLocations[elfsym.Value+2*uint64(ctxt.Arch.PtrSize)+8+1*uint64(ctxt.Arch.PtrSize)] = lsym
-			}
-		}
-		// For function symbols, we don't know what ABI is
-		// available, so alias it under both ABIs.
-		//
-		// TODO(austin): This is almost certainly wrong once
-		// the ABIs are actually different. We might have to
-		// mangle Go function names in the .so to include the
-		// ABI.
-		if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && ver == 0 {
-			var alias *sym.Symbol
-			if *flagNewobj {
-				i := ctxt.loader.AddExtSym(elfsym.Name, sym.SymVerABIInternal)
-				if i == 0 {
-					continue
-				}
-				alias = ctxt.Syms.Newsym(elfsym.Name, sym.SymVerABIInternal)
-				ctxt.loader.Syms[i] = alias
-			} else {
-				alias = ctxt.Syms.Lookup(elfsym.Name, sym.SymVerABIInternal)
-			}
-			if alias.Type != 0 {
-				continue
-			}
-			alias.Type = sym.SABIALIAS
-			alias.R = []sym.Reloc{{Sym: lsym}}
-		}
-	}
-	gcdataAddresses := make(map[*sym.Symbol]uint64)
-	if ctxt.Arch.Family == sys.ARM64 {
-		for _, sect := range f.Sections {
-			if sect.Type == elf.SHT_RELA {
-				var rela elf.Rela64
-				rdr := sect.Open()
-				for {
-					err := binary.Read(rdr, f.ByteOrder, &rela)
-					if err == io.EOF {
-						break
-					} else if err != nil {
-						Errorf(nil, "reading relocation failed %v", err)
-						return
-					}
-					t := elf.R_AARCH64(rela.Info & 0xffff)
-					if t != elf.R_AARCH64_RELATIVE {
-						continue
-					}
-					if lsym, ok := gcdataLocations[rela.Off]; ok {
-						gcdataAddresses[lsym] = uint64(rela.Addend)
-					}
-				}
-			}
-		}
-	}
-
-	ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdataAddresses: gcdataAddresses})
-}
-
-func addsection(arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section {
-	sect := new(sym.Section)
-	sect.Rwx = uint8(rwx)
-	sect.Name = name
-	sect.Seg = seg
-	sect.Align = int32(arch.PtrSize) // everything is at least pointer-aligned
-	seg.Sections = append(seg.Sections, sect)
-	return sect
-}
-
-type chain struct {
-	sym   *sym.Symbol
-	up    *chain
-	limit int // limit on entry to sym
-}
-
-var morestack *sym.Symbol
-
-// TODO: Record enough information in new object files to
-// allow stack checks here.
-
-func haslinkregister(ctxt *Link) bool {
-	return ctxt.FixedFrameSize() != 0
-}
-
-func callsize(ctxt *Link) int {
-	if haslinkregister(ctxt) {
-		return 0
-	}
-	return ctxt.Arch.RegSize
-}
-
-func (ctxt *Link) dostkcheck() {
-	var ch chain
-
-	morestack = ctxt.Syms.Lookup("runtime.morestack", 0)
-
-	// Every splitting function ensures that there are at least StackLimit
-	// bytes available below SP when the splitting prologue finishes.
-	// If the splitting function calls F, then F begins execution with
-	// at least StackLimit - callsize() bytes available.
-	// Check that every function behaves correctly with this amount
-	// of stack, following direct calls in order to piece together chains
-	// of non-splitting functions.
-	ch.up = nil
-
-	ch.limit = objabi.StackLimit - callsize(ctxt)
-	if objabi.GOARCH == "arm64" {
-		// need extra 8 bytes below SP to save FP
-		ch.limit -= 8
-	}
-
-	// Check every function, but do the nosplit functions in a first pass,
-	// to make the printed failure chains as short as possible.
-	for _, s := range ctxt.Textp {
-		// runtime.racesymbolizethunk is called from gcc-compiled C
-		// code running on the operating system thread stack.
-		// It uses more than the usual amount of stack but that's okay.
-		if s.Name == "runtime.racesymbolizethunk" {
-			continue
-		}
-
-		if s.Attr.NoSplit() {
-			ch.sym = s
-			stkcheck(ctxt, &ch, 0)
-		}
-	}
-
-	for _, s := range ctxt.Textp {
-		if !s.Attr.NoSplit() {
-			ch.sym = s
-			stkcheck(ctxt, &ch, 0)
-		}
-	}
-}
-
-func stkcheck(ctxt *Link, up *chain, depth int) int {
-	limit := up.limit
-	s := up.sym
-
-	// Don't duplicate work: only need to consider each
-	// function at top of safe zone once.
-	top := limit == objabi.StackLimit-callsize(ctxt)
-	if top {
-		if s.Attr.StackCheck() {
-			return 0
-		}
-		s.Attr |= sym.AttrStackCheck
-	}
-
-	if depth > 500 {
-		Errorf(s, "nosplit stack check too deep")
-		stkbroke(ctxt, up, 0)
-		return -1
-	}
-
-	if s.Attr.External() || s.FuncInfo == nil {
-		// external function.
-		// should never be called directly.
-		// onlyctxt.Diagnose the direct caller.
-		// TODO(mwhudson): actually think about this.
-		// TODO(khr): disabled for now. Calls to external functions can only happen on the g0 stack.
-		// See the trampolines in src/runtime/sys_darwin_$ARCH.go.
-		if depth == 1 && s.Type != sym.SXREF && !ctxt.DynlinkingGo() &&
-			ctxt.BuildMode != BuildModeCArchive && ctxt.BuildMode != BuildModePIE && ctxt.BuildMode != BuildModeCShared && ctxt.BuildMode != BuildModePlugin {
-			//Errorf(s, "call to external function")
-		}
-		return -1
-	}
-
-	if limit < 0 {
-		stkbroke(ctxt, up, limit)
-		return -1
-	}
-
-	// morestack looks like it calls functions,
-	// but it switches the stack pointer first.
-	if s == morestack {
-		return 0
-	}
-
-	var ch chain
-	ch.up = up
-
-	if !s.Attr.NoSplit() {
-		// Ensure we have enough stack to call morestack.
-		ch.limit = limit - callsize(ctxt)
-		ch.sym = morestack
-		if stkcheck(ctxt, &ch, depth+1) < 0 {
-			return -1
-		}
-		if !top {
-			return 0
-		}
-		// Raise limit to allow frame.
-		locals := int32(0)
-		if s.FuncInfo != nil {
-			locals = s.FuncInfo.Locals
-		}
-		limit = objabi.StackLimit + int(locals) + int(ctxt.FixedFrameSize())
-	}
-
-	// Walk through sp adjustments in function, consuming relocs.
-	ri := 0
-
-	endr := len(s.R)
-	var ch1 chain
-	pcsp := obj.NewPCIter(uint32(ctxt.Arch.MinLC))
-	var r *sym.Reloc
-	for pcsp.Init(s.FuncInfo.Pcsp.P); !pcsp.Done; pcsp.Next() {
-		// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
-
-		// Check stack size in effect for this span.
-		if int32(limit)-pcsp.Value < 0 {
-			stkbroke(ctxt, up, int(int32(limit)-pcsp.Value))
-			return -1
-		}
-
-		// Process calls in this span.
-		for ; ri < endr && uint32(s.R[ri].Off) < pcsp.NextPC; ri++ {
-			r = &s.R[ri]
-			switch {
-			case r.Type.IsDirectCall():
-				ch.limit = int(int32(limit) - pcsp.Value - int32(callsize(ctxt)))
-				ch.sym = r.Sym
-				if stkcheck(ctxt, &ch, depth+1) < 0 {
-					return -1
-				}
-
-			// Indirect call. Assume it is a call to a splitting function,
-			// so we have to make sure it can call morestack.
-			// Arrange the data structures to report both calls, so that
-			// if there is an error, stkprint shows all the steps involved.
-			case r.Type == objabi.R_CALLIND:
-				ch.limit = int(int32(limit) - pcsp.Value - int32(callsize(ctxt)))
-				ch.sym = nil
-				ch1.limit = ch.limit - callsize(ctxt) // for morestack in called prologue
-				ch1.up = &ch
-				ch1.sym = morestack
-				if stkcheck(ctxt, &ch1, depth+2) < 0 {
-					return -1
-				}
-			}
-		}
-	}
-
-	return 0
-}
-
-func stkbroke(ctxt *Link, ch *chain, limit int) {
-	Errorf(ch.sym, "nosplit stack overflow")
-	stkprint(ctxt, ch, limit)
-}
-
-func stkprint(ctxt *Link, ch *chain, limit int) {
-	var name string
-
-	if ch.sym != nil {
-		name = ch.sym.Name
-		if ch.sym.Attr.NoSplit() {
-			name += " (nosplit)"
-		}
-	} else {
-		name = "function pointer"
-	}
-
-	if ch.up == nil {
-		// top of chain.  ch->sym != nil.
-		if ch.sym.Attr.NoSplit() {
-			fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name)
-		} else {
-			fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name)
-		}
-	} else {
-		stkprint(ctxt, ch.up, ch.limit+callsize(ctxt))
-		if !haslinkregister(ctxt) {
-			fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name)
-		}
-	}
-
-	if ch.limit != limit {
-		fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit)
-	}
-}
-
-func usage() {
-	fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n")
-	objabi.Flagprint(os.Stderr)
-	Exit(2)
-}
-
-type SymbolType int8
-
-const (
-	// see also https://9p.io/magic/man2html/1/nm
-	TextSym      SymbolType = 'T'
-	DataSym      SymbolType = 'D'
-	BSSSym       SymbolType = 'B'
-	UndefinedSym SymbolType = 'U'
-	TLSSym       SymbolType = 't'
-	FrameSym     SymbolType = 'm'
-	ParamSym     SymbolType = 'p'
-	AutoSym      SymbolType = 'a'
-
-	// Deleted auto (not a real sym, just placeholder for type)
-	DeletedAutoSym = 'x'
-)
-
-func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int64, *sym.Symbol)) {
-	// These symbols won't show up in the first loop below because we
-	// skip sym.STEXT symbols. Normal sym.STEXT symbols are emitted by walking textp.
-	s := ctxt.Syms.Lookup("runtime.text", 0)
-	if s.Type == sym.STEXT {
-		// We've already included this symbol in ctxt.Textp
-		// if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin or
-		// on AIX with external linker.
-		// See data.go:/textaddress
-		if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
-			put(ctxt, s, s.Name, TextSym, s.Value, nil)
-		}
-	}
-
-	n := 0
-
-	// Generate base addresses for all text sections if there are multiple
-	for _, sect := range Segtext.Sections {
-		if n == 0 {
-			n++
-			continue
-		}
-		if sect.Name != ".text" || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
-			// On AIX, runtime.text.X are symbols already in the symtab.
-			break
-		}
-		s = ctxt.Syms.ROLookup(fmt.Sprintf("runtime.text.%d", n), 0)
-		if s == nil {
-			break
-		}
-		if s.Type == sym.STEXT {
-			put(ctxt, s, s.Name, TextSym, s.Value, nil)
-		}
-		n++
-	}
-
-	s = ctxt.Syms.Lookup("runtime.etext", 0)
-	if s.Type == sym.STEXT {
-		// We've already included this symbol in ctxt.Textp
-		// if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin or
-		// on AIX with external linker.
-		// See data.go:/textaddress
-		if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
-			put(ctxt, s, s.Name, TextSym, s.Value, nil)
-		}
-	}
-
-	shouldBeInSymbolTable := func(s *sym.Symbol) bool {
-		if s.Attr.NotInSymbolTable() {
-			return false
-		}
-		if ctxt.HeadType == objabi.Haix && s.Name == ".go.buildinfo" {
-			// On AIX, .go.buildinfo must be in the symbol table as
-			// it has relocations.
-			return true
-		}
-		if (s.Name == "" || s.Name[0] == '.') && !s.IsFileLocal() && s.Name != ".rathole" && s.Name != ".TOC." {
-			return false
-		}
-		return true
-	}
-
-	for _, s := range ctxt.Syms.Allsym {
-		if !shouldBeInSymbolTable(s) {
-			continue
-		}
-		switch s.Type {
-		case sym.SCONST,
-			sym.SRODATA,
-			sym.SSYMTAB,
-			sym.SPCLNTAB,
-			sym.SINITARR,
-			sym.SDATA,
-			sym.SNOPTRDATA,
-			sym.SELFROSECT,
-			sym.SMACHOGOT,
-			sym.STYPE,
-			sym.SSTRING,
-			sym.SGOSTRING,
-			sym.SGOFUNC,
-			sym.SGCBITS,
-			sym.STYPERELRO,
-			sym.SSTRINGRELRO,
-			sym.SGOSTRINGRELRO,
-			sym.SGOFUNCRELRO,
-			sym.SGCBITSRELRO,
-			sym.SRODATARELRO,
-			sym.STYPELINK,
-			sym.SITABLINK,
-			sym.SWINDOWS:
-			if !s.Attr.Reachable() {
-				continue
-			}
-			put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype)
-
-		case sym.SBSS, sym.SNOPTRBSS, sym.SLIBFUZZER_EXTRA_COUNTER:
-			if !s.Attr.Reachable() {
-				continue
-			}
-			if len(s.P) > 0 {
-				Errorf(s, "should not be bss (size=%d type=%v special=%v)", len(s.P), s.Type, s.Attr.Special())
-			}
-			put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype)
-
-		case sym.SUNDEFEXT:
-			if ctxt.HeadType == objabi.Hwindows || ctxt.HeadType == objabi.Haix || ctxt.IsELF {
-				put(ctxt, s, s.Name, UndefinedSym, s.Value, nil)
-			}
-
-		case sym.SHOSTOBJ:
-			if !s.Attr.Reachable() {
-				continue
-			}
-			if ctxt.HeadType == objabi.Hwindows || ctxt.IsELF {
-				put(ctxt, s, s.Name, UndefinedSym, s.Value, nil)
-			}
-
-		case sym.SDYNIMPORT:
-			if !s.Attr.Reachable() {
-				continue
-			}
-			put(ctxt, s, s.Extname(), UndefinedSym, 0, nil)
-
-		case sym.STLSBSS:
-			if ctxt.LinkMode == LinkExternal {
-				put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype)
-			}
-		}
-	}
-
-	for _, s := range ctxt.Textp {
-		put(ctxt, s, s.Name, TextSym, s.Value, s.Gotype)
-
-		locals := int32(0)
-		if s.FuncInfo != nil {
-			locals = s.FuncInfo.Locals
-		}
-		// NOTE(ality): acid can't produce a stack trace without .frame symbols
-		put(ctxt, nil, ".frame", FrameSym, int64(locals)+int64(ctxt.Arch.PtrSize), nil)
-
-		if s.FuncInfo == nil {
-			continue
-		}
-	}
-
-	if ctxt.Debugvlog != 0 || *flagN {
-		ctxt.Logf("symsize = %d\n", uint32(Symsize))
-	}
-}
-
-func Symaddr(s *sym.Symbol) int64 {
-	if !s.Attr.Reachable() {
-		Errorf(s, "unreachable symbol in symaddr")
-	}
-	return s.Value
-}
-
-func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) {
-	s := ctxt.Syms.Lookup(p, 0)
-	s.Type = t
-	s.Value = v
-	s.Attr |= sym.AttrReachable
-	s.Attr |= sym.AttrSpecial
-	s.Attr |= sym.AttrLocal
-}
-
-func datoff(s *sym.Symbol, addr int64) int64 {
-	if uint64(addr) >= Segdata.Vaddr {
-		return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
-	}
-	if uint64(addr) >= Segtext.Vaddr {
-		return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff)
-	}
-	Errorf(s, "invalid datoff %#x", addr)
-	return 0
-}
-
-func Entryvalue(ctxt *Link) int64 {
-	a := *flagEntrySymbol
-	if a[0] >= '0' && a[0] <= '9' {
-		return atolwhex(a)
-	}
-	s := ctxt.Syms.Lookup(a, 0)
-	if s.Type == 0 {
-		return *FlagTextAddr
-	}
-	if ctxt.HeadType != objabi.Haix && s.Type != sym.STEXT {
-		Errorf(s, "entry not text")
-	}
-	return s.Value
-}
-
-func undefsym(ctxt *Link, s *sym.Symbol) {
-	var r *sym.Reloc
-
-	for i := 0; i < len(s.R); i++ {
-		r = &s.R[i]
-		if r.Sym == nil { // happens for some external ARM relocs
-			continue
-		}
-		// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
-		// sense and should be removed when someone has thought about it properly.
-		if (r.Sym.Type == sym.Sxxx || r.Sym.Type == sym.SXREF) && !r.Sym.Attr.VisibilityHidden() {
-			Errorf(s, "undefined: %q", r.Sym.Name)
-		}
-		if !r.Sym.Attr.Reachable() && r.Type != objabi.R_WEAKADDROFF {
-			Errorf(s, "relocation target %q", r.Sym.Name)
-		}
-	}
-}
-
-func (ctxt *Link) undef() {
-	// undefsym performs checks (almost) identical to checks
-	// that report undefined relocations in relocsym.
-	// Both undefsym and relocsym can report same symbol as undefined,
-	// which results in error message duplication (see #10978).
-	//
-	// The undef is run after Arch.Asmb and could detect some
-	// programming errors there, but if object being linked is already
-	// failed with errors, it is better to avoid duplicated errors.
-	if nerrors > 0 {
-		return
-	}
-
-	for _, s := range ctxt.Textp {
-		undefsym(ctxt, s)
-	}
-	for _, s := range datap {
-		undefsym(ctxt, s)
-	}
-	if nerrors > 0 {
-		errorexit()
-	}
-}
-
-func (ctxt *Link) callgraph() {
-	if !*FlagC {
-		return
-	}
-
-	var i int
-	var r *sym.Reloc
-	for _, s := range ctxt.Textp {
-		for i = 0; i < len(s.R); i++ {
-			r = &s.R[i]
-			if r.Sym == nil {
-				continue
-			}
-			if r.Type.IsDirectCall() && r.Sym.Type == sym.STEXT {
-				ctxt.Logf("%s calls %s\n", s.Name, r.Sym.Name)
-			}
-		}
-	}
-}
-
-func Rnd(v int64, r int64) int64 {
-	if r <= 0 {
-		return v
-	}
-	v += r - 1
-	c := v % r
-	if c < 0 {
-		c += r
-	}
-	v -= c
-	return v
-}
-
-func bgetc(r *bio.Reader) int {
-	c, err := r.ReadByte()
-	if err != nil {
-		if err != io.EOF {
-			log.Fatalf("reading input: %v", err)
-		}
-		return -1
-	}
-	return int(c)
-}
-
-type markKind uint8 // for postorder traversal
-const (
-	_ markKind = iota
-	visiting
-	visited
-)
-
-func postorder(libs []*sym.Library) []*sym.Library {
-	order := make([]*sym.Library, 0, len(libs)) // hold the result
-	mark := make(map[*sym.Library]markKind, len(libs))
-	for _, lib := range libs {
-		dfs(lib, mark, &order)
-	}
-	return order
-}
-
-func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library) {
-	if mark[lib] == visited {
-		return
-	}
-	if mark[lib] == visiting {
-		panic("found import cycle while visiting " + lib.Pkg)
-	}
-	mark[lib] = visiting
-	for _, i := range lib.Imports {
-		dfs(i, mark, order)
-	}
-	mark[lib] = visited
-	*order = append(*order, lib)
-}
-
-func (ctxt *Link) loadlibfull() {
-	// Load full symbol contents, resolve indexed references.
-	ctxt.loader.LoadFull(ctxt.Arch, ctxt.Syms)
-
-	// Pull the symbols out.
-	ctxt.loader.ExtractSymbols(ctxt.Syms)
-
-	// Load cgo directives.
-	for _, d := range ctxt.cgodata {
-		setCgoAttr(ctxt, ctxt.Syms.Lookup, d.file, d.pkg, d.directives)
-	}
-
-	setupdynexp(ctxt)
-
-	// Populate ctxt.Reachparent if appropriate.
-	if ctxt.Reachparent != nil {
-		for i := 0; i < len(ctxt.loader.Reachparent); i++ {
-			p := ctxt.loader.Reachparent[i]
-			if p == 0 {
-				continue
-			}
-			if p == loader.Sym(i) {
-				panic("self-cycle in reachparent")
-			}
-			sym := ctxt.loader.Syms[i]
-			psym := ctxt.loader.Syms[p]
-			ctxt.Reachparent[sym] = psym
-		}
-	}
-
-	// Drop the reference.
-	ctxt.loader = nil
-	ctxt.cgodata = nil
-
-	addToTextp(ctxt)
-}
-
-func (ctxt *Link) dumpsyms() {
-	for _, s := range ctxt.Syms.Allsym {
-		fmt.Printf("%s %s %p %v %v\n", s, s.Type, s, s.Attr.Reachable(), s.Attr.OnList())
-		for i := range s.R {
-			fmt.Println("\t", s.R[i].Type, s.R[i].Sym)
-		}
-	}
-}
diff --git a/src/cmd/oldlink/internal/ld/link.go b/src/cmd/oldlink/internal/ld/link.go
deleted file mode 100644
index 15878f3..0000000
--- a/src/cmd/oldlink/internal/ld/link.go
+++ /dev/null
@@ -1,187 +0,0 @@
-// Derived from Inferno utils/6l/l.h and related files.
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ld
-
-import (
-	"bufio"
-	"cmd/internal/obj"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/loader"
-	"cmd/oldlink/internal/sym"
-	"debug/elf"
-	"fmt"
-)
-
-type Shlib struct {
-	Path            string
-	Hash            []byte
-	Deps            []string
-	File            *elf.File
-	gcdataAddresses map[*sym.Symbol]uint64
-}
-
-// Link holds the context for writing object code from a compiler
-// or for reading that input into the linker.
-type Link struct {
-	Out *OutBuf
-
-	Syms *sym.Symbols
-
-	Arch      *sys.Arch
-	Debugvlog int
-	Bso       *bufio.Writer
-
-	Loaded bool // set after all inputs have been loaded as symbols
-
-	IsELF    bool
-	HeadType objabi.HeadType
-
-	linkShared    bool // link against installed Go shared libraries
-	LinkMode      LinkMode
-	BuildMode     BuildMode
-	canUsePlugins bool // initialized when Loaded is set to true
-	compressDWARF bool
-
-	Tlsg         *sym.Symbol
-	Libdir       []string
-	Library      []*sym.Library
-	LibraryByPkg map[string]*sym.Library
-	Shlibs       []Shlib
-	Tlsoffset    int
-	Textp        []*sym.Symbol
-	Filesyms     []*sym.Symbol
-	Moduledata   *sym.Symbol
-
-	PackageFile  map[string]string
-	PackageShlib map[string]string
-
-	tramps []*sym.Symbol // trampolines
-
-	// unresolvedSymSet is a set of erroneous unresolved references.
-	// Used to avoid duplicated error messages.
-	unresolvedSymSet map[unresolvedSymKey]bool
-
-	// Used to implement field tracking.
-	Reachparent map[*sym.Symbol]*sym.Symbol
-
-	compUnits []*sym.CompilationUnit // DWARF compilation units
-	runtimeCU *sym.CompilationUnit   // One of the runtime CUs, the last one seen.
-
-	relocbuf []byte // temporary buffer for applying relocations
-
-	loader  *loader.Loader
-	cgodata []cgodata // cgo directives to load, three strings are args for loadcgo
-
-	cgo_export_static  map[string]bool
-	cgo_export_dynamic map[string]bool
-}
-
-type cgodata struct {
-	file       string
-	pkg        string
-	directives [][]string
-}
-
-type unresolvedSymKey struct {
-	from *sym.Symbol // Symbol that referenced unresolved "to"
-	to   *sym.Symbol // Unresolved symbol referenced by "from"
-}
-
-// ErrorUnresolved prints unresolved symbol error for r.Sym that is referenced from s.
-func (ctxt *Link) ErrorUnresolved(s *sym.Symbol, r *sym.Reloc) {
-	if ctxt.unresolvedSymSet == nil {
-		ctxt.unresolvedSymSet = make(map[unresolvedSymKey]bool)
-	}
-
-	k := unresolvedSymKey{from: s, to: r.Sym}
-	if !ctxt.unresolvedSymSet[k] {
-		ctxt.unresolvedSymSet[k] = true
-
-		// Try to find symbol under another ABI.
-		var reqABI, haveABI obj.ABI
-		haveABI = ^obj.ABI(0)
-		reqABI, ok := sym.VersionToABI(int(r.Sym.Version))
-		if ok {
-			for abi := obj.ABI(0); abi < obj.ABICount; abi++ {
-				v := sym.ABIToVersion(abi)
-				if v == -1 {
-					continue
-				}
-				if rs := ctxt.Syms.ROLookup(r.Sym.Name, v); rs != nil && rs.Type != sym.Sxxx && rs.Type != sym.SXREF {
-					haveABI = abi
-				}
-			}
-		}
-
-		// Give a special error message for main symbol (see #24809).
-		if r.Sym.Name == "main.main" {
-			Errorf(s, "function main is undeclared in the main package")
-		} else if haveABI != ^obj.ABI(0) {
-			Errorf(s, "relocation target %s not defined for %s (but is defined for %s)", r.Sym.Name, reqABI, haveABI)
-		} else {
-			Errorf(s, "relocation target %s not defined", r.Sym.Name)
-		}
-	}
-}
-
-// The smallest possible offset from the hardware stack pointer to a local
-// variable on the stack. Architectures that use a link register save its value
-// on the stack in the function prologue and so always have a pointer between
-// the hardware stack pointer and the local variable area.
-func (ctxt *Link) FixedFrameSize() int64 {
-	switch ctxt.Arch.Family {
-	case sys.AMD64, sys.I386:
-		return 0
-	case sys.PPC64:
-		// PIC code on ppc64le requires 32 bytes of stack, and it's easier to
-		// just use that much stack always on ppc64x.
-		return int64(4 * ctxt.Arch.PtrSize)
-	default:
-		return int64(ctxt.Arch.PtrSize)
-	}
-}
-
-func (ctxt *Link) Logf(format string, args ...interface{}) {
-	fmt.Fprintf(ctxt.Bso, format, args...)
-	ctxt.Bso.Flush()
-}
-
-func addImports(ctxt *Link, l *sym.Library, pn string) {
-	pkg := objabi.PathToPrefix(l.Pkg)
-	for _, importStr := range l.ImportStrings {
-		lib := addlib(ctxt, pkg, pn, importStr)
-		if lib != nil {
-			l.Imports = append(l.Imports, lib)
-		}
-	}
-	l.ImportStrings = nil
-}
diff --git a/src/cmd/oldlink/internal/ld/macho.go b/src/cmd/oldlink/internal/ld/macho.go
deleted file mode 100644
index 960ed29..0000000
--- a/src/cmd/oldlink/internal/ld/macho.go
+++ /dev/null
@@ -1,1119 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ld
-
-import (
-	"bytes"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/sym"
-	"debug/macho"
-	"encoding/binary"
-	"fmt"
-	"io"
-	"os"
-	"sort"
-	"strings"
-)
-
-type MachoHdr struct {
-	cpu    uint32
-	subcpu uint32
-}
-
-type MachoSect struct {
-	name    string
-	segname string
-	addr    uint64
-	size    uint64
-	off     uint32
-	align   uint32
-	reloc   uint32
-	nreloc  uint32
-	flag    uint32
-	res1    uint32
-	res2    uint32
-}
-
-type MachoSeg struct {
-	name       string
-	vsize      uint64
-	vaddr      uint64
-	fileoffset uint64
-	filesize   uint64
-	prot1      uint32
-	prot2      uint32
-	nsect      uint32
-	msect      uint32
-	sect       []MachoSect
-	flag       uint32
-}
-
-// MachoPlatformLoad represents a LC_VERSION_MIN_* or
-// LC_BUILD_VERSION load command.
-type MachoPlatformLoad struct {
-	platform MachoPlatform // One of PLATFORM_* constants.
-	cmd      MachoLoad
-}
-
-type MachoLoad struct {
-	type_ uint32
-	data  []uint32
-}
-
-type MachoPlatform int
-
-/*
- * Total amount of space to reserve at the start of the file
- * for Header, PHeaders, and SHeaders.
- * May waste some.
- */
-const (
-	INITIAL_MACHO_HEADR = 4 * 1024
-)
-
-const (
-	MACHO_CPU_AMD64               = 1<<24 | 7
-	MACHO_CPU_386                 = 7
-	MACHO_SUBCPU_X86              = 3
-	MACHO_CPU_ARM                 = 12
-	MACHO_SUBCPU_ARM              = 0
-	MACHO_SUBCPU_ARMV7            = 9
-	MACHO_CPU_ARM64               = 1<<24 | 12
-	MACHO_SUBCPU_ARM64_ALL        = 0
-	MACHO32SYMSIZE                = 12
-	MACHO64SYMSIZE                = 16
-	MACHO_X86_64_RELOC_UNSIGNED   = 0
-	MACHO_X86_64_RELOC_SIGNED     = 1
-	MACHO_X86_64_RELOC_BRANCH     = 2
-	MACHO_X86_64_RELOC_GOT_LOAD   = 3
-	MACHO_X86_64_RELOC_GOT        = 4
-	MACHO_X86_64_RELOC_SUBTRACTOR = 5
-	MACHO_X86_64_RELOC_SIGNED_1   = 6
-	MACHO_X86_64_RELOC_SIGNED_2   = 7
-	MACHO_X86_64_RELOC_SIGNED_4   = 8
-	MACHO_ARM_RELOC_VANILLA       = 0
-	MACHO_ARM_RELOC_PAIR          = 1
-	MACHO_ARM_RELOC_SECTDIFF      = 2
-	MACHO_ARM_RELOC_BR24          = 5
-	MACHO_ARM64_RELOC_UNSIGNED    = 0
-	MACHO_ARM64_RELOC_BRANCH26    = 2
-	MACHO_ARM64_RELOC_PAGE21      = 3
-	MACHO_ARM64_RELOC_PAGEOFF12   = 4
-	MACHO_ARM64_RELOC_ADDEND      = 10
-	MACHO_GENERIC_RELOC_VANILLA   = 0
-	MACHO_FAKE_GOTPCREL           = 100
-)
-
-const (
-	MH_MAGIC    = 0xfeedface
-	MH_MAGIC_64 = 0xfeedfacf
-
-	MH_OBJECT  = 0x1
-	MH_EXECUTE = 0x2
-
-	MH_NOUNDEFS = 0x1
-)
-
-const (
-	LC_SEGMENT                  = 0x1
-	LC_SYMTAB                   = 0x2
-	LC_SYMSEG                   = 0x3
-	LC_THREAD                   = 0x4
-	LC_UNIXTHREAD               = 0x5
-	LC_LOADFVMLIB               = 0x6
-	LC_IDFVMLIB                 = 0x7
-	LC_IDENT                    = 0x8
-	LC_FVMFILE                  = 0x9
-	LC_PREPAGE                  = 0xa
-	LC_DYSYMTAB                 = 0xb
-	LC_LOAD_DYLIB               = 0xc
-	LC_ID_DYLIB                 = 0xd
-	LC_LOAD_DYLINKER            = 0xe
-	LC_ID_DYLINKER              = 0xf
-	LC_PREBOUND_DYLIB           = 0x10
-	LC_ROUTINES                 = 0x11
-	LC_SUB_FRAMEWORK            = 0x12
-	LC_SUB_UMBRELLA             = 0x13
-	LC_SUB_CLIENT               = 0x14
-	LC_SUB_LIBRARY              = 0x15
-	LC_TWOLEVEL_HINTS           = 0x16
-	LC_PREBIND_CKSUM            = 0x17
-	LC_LOAD_WEAK_DYLIB          = 0x80000018
-	LC_SEGMENT_64               = 0x19
-	LC_ROUTINES_64              = 0x1a
-	LC_UUID                     = 0x1b
-	LC_RPATH                    = 0x8000001c
-	LC_CODE_SIGNATURE           = 0x1d
-	LC_SEGMENT_SPLIT_INFO       = 0x1e
-	LC_REEXPORT_DYLIB           = 0x8000001f
-	LC_LAZY_LOAD_DYLIB          = 0x20
-	LC_ENCRYPTION_INFO          = 0x21
-	LC_DYLD_INFO                = 0x22
-	LC_DYLD_INFO_ONLY           = 0x80000022
-	LC_LOAD_UPWARD_DYLIB        = 0x80000023
-	LC_VERSION_MIN_MACOSX       = 0x24
-	LC_VERSION_MIN_IPHONEOS     = 0x25
-	LC_FUNCTION_STARTS          = 0x26
-	LC_DYLD_ENVIRONMENT         = 0x27
-	LC_MAIN                     = 0x80000028
-	LC_DATA_IN_CODE             = 0x29
-	LC_SOURCE_VERSION           = 0x2A
-	LC_DYLIB_CODE_SIGN_DRS      = 0x2B
-	LC_ENCRYPTION_INFO_64       = 0x2C
-	LC_LINKER_OPTION            = 0x2D
-	LC_LINKER_OPTIMIZATION_HINT = 0x2E
-	LC_VERSION_MIN_TVOS         = 0x2F
-	LC_VERSION_MIN_WATCHOS      = 0x30
-	LC_VERSION_NOTE             = 0x31
-	LC_BUILD_VERSION            = 0x32
-)
-
-const (
-	S_REGULAR                  = 0x0
-	S_ZEROFILL                 = 0x1
-	S_NON_LAZY_SYMBOL_POINTERS = 0x6
-	S_SYMBOL_STUBS             = 0x8
-	S_MOD_INIT_FUNC_POINTERS   = 0x9
-	S_ATTR_PURE_INSTRUCTIONS   = 0x80000000
-	S_ATTR_DEBUG               = 0x02000000
-	S_ATTR_SOME_INSTRUCTIONS   = 0x00000400
-)
-
-const (
-	PLATFORM_MACOS    MachoPlatform = 1
-	PLATFORM_IOS      MachoPlatform = 2
-	PLATFORM_TVOS     MachoPlatform = 3
-	PLATFORM_WATCHOS  MachoPlatform = 4
-	PLATFORM_BRIDGEOS MachoPlatform = 5
-)
-
-// Mach-O file writing
-// https://developer.apple.com/mac/library/DOCUMENTATION/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
-
-var machohdr MachoHdr
-
-var load []MachoLoad
-
-var machoPlatform MachoPlatform
-
-var seg [16]MachoSeg
-
-var nseg int
-
-var ndebug int
-
-var nsect int
-
-const (
-	SymKindLocal = 0 + iota
-	SymKindExtdef
-	SymKindUndef
-	NumSymKind
-)
-
-var nkind [NumSymKind]int
-
-var sortsym []*sym.Symbol
-
-var nsortsym int
-
-// Amount of space left for adding load commands
-// that refer to dynamic libraries. Because these have
-// to go in the Mach-O header, we can't just pick a
-// "big enough" header size. The initial header is
-// one page, the non-dynamic library stuff takes
-// up about 1300 bytes; we overestimate that as 2k.
-var loadBudget = INITIAL_MACHO_HEADR - 2*1024
-
-func getMachoHdr() *MachoHdr {
-	return &machohdr
-}
-
-func newMachoLoad(arch *sys.Arch, type_ uint32, ndata uint32) *MachoLoad {
-	if arch.PtrSize == 8 && (ndata&1 != 0) {
-		ndata++
-	}
-
-	load = append(load, MachoLoad{})
-	l := &load[len(load)-1]
-	l.type_ = type_
-	l.data = make([]uint32, ndata)
-	return l
-}
-
-func newMachoSeg(name string, msect int) *MachoSeg {
-	if nseg >= len(seg) {
-		Exitf("too many segs")
-	}
-
-	s := &seg[nseg]
-	nseg++
-	s.name = name
-	s.msect = uint32(msect)
-	s.sect = make([]MachoSect, msect)
-	return s
-}
-
-func newMachoSect(seg *MachoSeg, name string, segname string) *MachoSect {
-	if seg.nsect >= seg.msect {
-		Exitf("too many sects in segment %s", seg.name)
-	}
-
-	s := &seg.sect[seg.nsect]
-	seg.nsect++
-	s.name = name
-	s.segname = segname
-	nsect++
-	return s
-}
-
-// Generic linking code.
-
-var dylib []string
-
-var linkoff int64
-
-func machowrite(arch *sys.Arch, out *OutBuf, linkmode LinkMode) int {
-	o1 := out.Offset()
-
-	loadsize := 4 * 4 * ndebug
-	for i := range load {
-		loadsize += 4 * (len(load[i].data) + 2)
-	}
-	if arch.PtrSize == 8 {
-		loadsize += 18 * 4 * nseg
-		loadsize += 20 * 4 * nsect
-	} else {
-		loadsize += 14 * 4 * nseg
-		loadsize += 17 * 4 * nsect
-	}
-
-	if arch.PtrSize == 8 {
-		out.Write32(MH_MAGIC_64)
-	} else {
-		out.Write32(MH_MAGIC)
-	}
-	out.Write32(machohdr.cpu)
-	out.Write32(machohdr.subcpu)
-	if linkmode == LinkExternal {
-		out.Write32(MH_OBJECT) /* file type - mach object */
-	} else {
-		out.Write32(MH_EXECUTE) /* file type - mach executable */
-	}
-	out.Write32(uint32(len(load)) + uint32(nseg) + uint32(ndebug))
-	out.Write32(uint32(loadsize))
-	if nkind[SymKindUndef] == 0 {
-		out.Write32(MH_NOUNDEFS) /* flags - no undefines */
-	} else {
-		out.Write32(0) /* flags */
-	}
-	if arch.PtrSize == 8 {
-		out.Write32(0) /* reserved */
-	}
-
-	for i := 0; i < nseg; i++ {
-		s := &seg[i]
-		if arch.PtrSize == 8 {
-			out.Write32(LC_SEGMENT_64)
-			out.Write32(72 + 80*s.nsect)
-			out.WriteStringN(s.name, 16)
-			out.Write64(s.vaddr)
-			out.Write64(s.vsize)
-			out.Write64(s.fileoffset)
-			out.Write64(s.filesize)
-			out.Write32(s.prot1)
-			out.Write32(s.prot2)
-			out.Write32(s.nsect)
-			out.Write32(s.flag)
-		} else {
-			out.Write32(LC_SEGMENT)
-			out.Write32(56 + 68*s.nsect)
-			out.WriteStringN(s.name, 16)
-			out.Write32(uint32(s.vaddr))
-			out.Write32(uint32(s.vsize))
-			out.Write32(uint32(s.fileoffset))
-			out.Write32(uint32(s.filesize))
-			out.Write32(s.prot1)
-			out.Write32(s.prot2)
-			out.Write32(s.nsect)
-			out.Write32(s.flag)
-		}
-
-		for j := uint32(0); j < s.nsect; j++ {
-			t := &s.sect[j]
-			if arch.PtrSize == 8 {
-				out.WriteStringN(t.name, 16)
-				out.WriteStringN(t.segname, 16)
-				out.Write64(t.addr)
-				out.Write64(t.size)
-				out.Write32(t.off)
-				out.Write32(t.align)
-				out.Write32(t.reloc)
-				out.Write32(t.nreloc)
-				out.Write32(t.flag)
-				out.Write32(t.res1) /* reserved */
-				out.Write32(t.res2) /* reserved */
-				out.Write32(0)      /* reserved */
-			} else {
-				out.WriteStringN(t.name, 16)
-				out.WriteStringN(t.segname, 16)
-				out.Write32(uint32(t.addr))
-				out.Write32(uint32(t.size))
-				out.Write32(t.off)
-				out.Write32(t.align)
-				out.Write32(t.reloc)
-				out.Write32(t.nreloc)
-				out.Write32(t.flag)
-				out.Write32(t.res1) /* reserved */
-				out.Write32(t.res2) /* reserved */
-			}
-		}
-	}
-
-	for i := range load {
-		l := &load[i]
-		out.Write32(l.type_)
-		out.Write32(4 * (uint32(len(l.data)) + 2))
-		for j := 0; j < len(l.data); j++ {
-			out.Write32(l.data[j])
-		}
-	}
-
-	return int(out.Offset() - o1)
-}
-
-func (ctxt *Link) domacho() {
-	if *FlagD {
-		return
-	}
-
-	// Copy platform load command.
-	for _, h := range hostobj {
-		load, err := hostobjMachoPlatform(&h)
-		if err != nil {
-			Exitf("%v", err)
-		}
-		if load != nil {
-			machoPlatform = load.platform
-			ml := newMachoLoad(ctxt.Arch, load.cmd.type_, uint32(len(load.cmd.data)))
-			copy(ml.data, load.cmd.data)
-			break
-		}
-	}
-	if machoPlatform == 0 {
-		switch ctxt.Arch.Family {
-		default:
-			machoPlatform = PLATFORM_MACOS
-			if ctxt.LinkMode == LinkInternal {
-				// For lldb, must say LC_VERSION_MIN_MACOSX or else
-				// it won't know that this Mach-O binary is from OS X
-				// (could be iOS or WatchOS instead).
-				// Go on iOS uses linkmode=external, and linkmode=external
-				// adds this itself. So we only need this code for linkmode=internal
-				// and we can assume OS X.
-				//
-				// See golang.org/issues/12941.
-				//
-				// The version must be at least 10.9; see golang.org/issues/30488.
-				ml := newMachoLoad(ctxt.Arch, LC_VERSION_MIN_MACOSX, 2)
-				ml.data[0] = 10<<16 | 9<<8 | 0<<0 // OS X version 10.9.0
-				ml.data[1] = 10<<16 | 9<<8 | 0<<0 // SDK 10.9.0
-			}
-		case sys.ARM, sys.ARM64:
-			machoPlatform = PLATFORM_IOS
-		}
-	}
-
-	// empirically, string table must begin with " \x00".
-	s := ctxt.Syms.Lookup(".machosymstr", 0)
-
-	s.Type = sym.SMACHOSYMSTR
-	s.Attr |= sym.AttrReachable
-	s.AddUint8(' ')
-	s.AddUint8('\x00')
-
-	s = ctxt.Syms.Lookup(".machosymtab", 0)
-	s.Type = sym.SMACHOSYMTAB
-	s.Attr |= sym.AttrReachable
-
-	if ctxt.LinkMode != LinkExternal {
-		s := ctxt.Syms.Lookup(".plt", 0) // will be __symbol_stub
-		s.Type = sym.SMACHOPLT
-		s.Attr |= sym.AttrReachable
-
-		s = ctxt.Syms.Lookup(".got", 0) // will be __nl_symbol_ptr
-		s.Type = sym.SMACHOGOT
-		s.Attr |= sym.AttrReachable
-		s.Align = 4
-
-		s = ctxt.Syms.Lookup(".linkedit.plt", 0) // indirect table for .plt
-		s.Type = sym.SMACHOINDIRECTPLT
-		s.Attr |= sym.AttrReachable
-
-		s = ctxt.Syms.Lookup(".linkedit.got", 0) // indirect table for .got
-		s.Type = sym.SMACHOINDIRECTGOT
-		s.Attr |= sym.AttrReachable
-	}
-
-	// Add a dummy symbol that will become the __asm marker section.
-	if ctxt.LinkMode == LinkExternal {
-		s := ctxt.Syms.Lookup(".llvmasm", 0)
-		s.Type = sym.SMACHO
-		s.Attr |= sym.AttrReachable
-		s.AddUint8(0)
-	}
-}
-
-func machoadddynlib(lib string, linkmode LinkMode) {
-	if seenlib[lib] || linkmode == LinkExternal {
-		return
-	}
-	seenlib[lib] = true
-
-	// Will need to store the library name rounded up
-	// and 24 bytes of header metadata. If not enough
-	// space, grab another page of initial space at the
-	// beginning of the output file.
-	loadBudget -= (len(lib)+7)/8*8 + 24
-
-	if loadBudget < 0 {
-		HEADR += 4096
-		*FlagTextAddr += 4096
-		loadBudget += 4096
-	}
-
-	dylib = append(dylib, lib)
-}
-
-func machoshbits(ctxt *Link, mseg *MachoSeg, sect *sym.Section, segname string) {
-	buf := "__" + strings.Replace(sect.Name[1:], ".", "_", -1)
-
-	var msect *MachoSect
-	if sect.Rwx&1 == 0 && segname != "__DWARF" && (ctxt.Arch.Family == sys.ARM64 ||
-		ctxt.Arch.Family == sys.ARM ||
-		(ctxt.Arch.Family == sys.AMD64 && ctxt.BuildMode != BuildModeExe)) {
-		// Darwin external linker on arm and arm64, and on amd64 in c-shared/c-archive buildmode
-		// complains about absolute relocs in __TEXT, so if the section is not
-		// executable, put it in __DATA segment.
-		msect = newMachoSect(mseg, buf, "__DATA")
-	} else {
-		msect = newMachoSect(mseg, buf, segname)
-	}
-
-	if sect.Rellen > 0 {
-		msect.reloc = uint32(sect.Reloff)
-		msect.nreloc = uint32(sect.Rellen / 8)
-	}
-
-	for 1<<msect.align < sect.Align {
-		msect.align++
-	}
-	msect.addr = sect.Vaddr
-	msect.size = sect.Length
-
-	if sect.Vaddr < sect.Seg.Vaddr+sect.Seg.Filelen {
-		// data in file
-		if sect.Length > sect.Seg.Vaddr+sect.Seg.Filelen-sect.Vaddr {
-			Errorf(nil, "macho cannot represent section %s crossing data and bss", sect.Name)
-		}
-		msect.off = uint32(sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr)
-	} else {
-		msect.off = 0
-		msect.flag |= S_ZEROFILL
-	}
-
-	if sect.Rwx&1 != 0 {
-		msect.flag |= S_ATTR_SOME_INSTRUCTIONS
-	}
-
-	if sect.Name == ".text" {
-		msect.flag |= S_ATTR_PURE_INSTRUCTIONS
-	}
-
-	if sect.Name == ".plt" {
-		msect.name = "__symbol_stub1"
-		msect.flag = S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS | S_SYMBOL_STUBS
-		msect.res1 = 0 //nkind[SymKindLocal];
-		msect.res2 = 6
-	}
-
-	if sect.Name == ".got" {
-		msect.name = "__nl_symbol_ptr"
-		msect.flag = S_NON_LAZY_SYMBOL_POINTERS
-		msect.res1 = uint32(ctxt.Syms.Lookup(".linkedit.plt", 0).Size / 4) /* offset into indirect symbol table */
-	}
-
-	if sect.Name == ".init_array" {
-		msect.name = "__mod_init_func"
-		msect.flag = S_MOD_INIT_FUNC_POINTERS
-	}
-
-	// Some platforms such as watchOS and tvOS require binaries with
-	// bitcode enabled. The Go toolchain can't output bitcode, so use
-	// a marker section in the __LLVM segment, "__asm", to tell the Apple
-	// toolchain that the Go text came from assembler and thus has no
-	// bitcode. This is not true, but Kotlin/Native, Rust and Flutter
-	// are also using this trick.
-	if sect.Name == ".llvmasm" {
-		msect.name = "__asm"
-		msect.segname = "__LLVM"
-	}
-
-	if segname == "__DWARF" {
-		msect.flag |= S_ATTR_DEBUG
-	}
-}
-
-func Asmbmacho(ctxt *Link) {
-	/* apple MACH */
-	va := *FlagTextAddr - int64(HEADR)
-
-	mh := getMachoHdr()
-	switch ctxt.Arch.Family {
-	default:
-		Exitf("unknown macho architecture: %v", ctxt.Arch.Family)
-
-	case sys.ARM:
-		mh.cpu = MACHO_CPU_ARM
-		mh.subcpu = MACHO_SUBCPU_ARMV7
-
-	case sys.AMD64:
-		mh.cpu = MACHO_CPU_AMD64
-		mh.subcpu = MACHO_SUBCPU_X86
-
-	case sys.ARM64:
-		mh.cpu = MACHO_CPU_ARM64
-		mh.subcpu = MACHO_SUBCPU_ARM64_ALL
-
-	case sys.I386:
-		mh.cpu = MACHO_CPU_386
-		mh.subcpu = MACHO_SUBCPU_X86
-	}
-
-	var ms *MachoSeg
-	if ctxt.LinkMode == LinkExternal {
-		/* segment for entire file */
-		ms = newMachoSeg("", 40)
-
-		ms.fileoffset = Segtext.Fileoff
-		ms.filesize = Segdwarf.Fileoff + Segdwarf.Filelen - Segtext.Fileoff
-		ms.vsize = Segdwarf.Vaddr + Segdwarf.Length - Segtext.Vaddr
-	}
-
-	/* segment for zero page */
-	if ctxt.LinkMode != LinkExternal {
-		ms = newMachoSeg("__PAGEZERO", 0)
-		ms.vsize = uint64(va)
-	}
-
-	/* text */
-	v := Rnd(int64(uint64(HEADR)+Segtext.Length), int64(*FlagRound))
-
-	if ctxt.LinkMode != LinkExternal {
-		ms = newMachoSeg("__TEXT", 20)
-		ms.vaddr = uint64(va)
-		ms.vsize = uint64(v)
-		ms.fileoffset = 0
-		ms.filesize = uint64(v)
-		ms.prot1 = 7
-		ms.prot2 = 5
-	}
-
-	for _, sect := range Segtext.Sections {
-		machoshbits(ctxt, ms, sect, "__TEXT")
-	}
-
-	/* data */
-	if ctxt.LinkMode != LinkExternal {
-		w := int64(Segdata.Length)
-		ms = newMachoSeg("__DATA", 20)
-		ms.vaddr = uint64(va) + uint64(v)
-		ms.vsize = uint64(w)
-		ms.fileoffset = uint64(v)
-		ms.filesize = Segdata.Filelen
-		ms.prot1 = 3
-		ms.prot2 = 3
-	}
-
-	for _, sect := range Segdata.Sections {
-		machoshbits(ctxt, ms, sect, "__DATA")
-	}
-
-	/* dwarf */
-	if !*FlagW {
-		if ctxt.LinkMode != LinkExternal {
-			ms = newMachoSeg("__DWARF", 20)
-			ms.vaddr = Segdwarf.Vaddr
-			ms.vsize = 0
-			ms.fileoffset = Segdwarf.Fileoff
-			ms.filesize = Segdwarf.Filelen
-		}
-		for _, sect := range Segdwarf.Sections {
-			machoshbits(ctxt, ms, sect, "__DWARF")
-		}
-	}
-
-	if ctxt.LinkMode != LinkExternal {
-		switch ctxt.Arch.Family {
-		default:
-			Exitf("unknown macho architecture: %v", ctxt.Arch.Family)
-
-		case sys.ARM:
-			ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 17+2)
-			ml.data[0] = 1                           /* thread type */
-			ml.data[1] = 17                          /* word count */
-			ml.data[2+15] = uint32(Entryvalue(ctxt)) /* start pc */
-
-		case sys.AMD64:
-			ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 42+2)
-			ml.data[0] = 4                           /* thread type */
-			ml.data[1] = 42                          /* word count */
-			ml.data[2+32] = uint32(Entryvalue(ctxt)) /* start pc */
-			ml.data[2+32+1] = uint32(Entryvalue(ctxt) >> 32)
-
-		case sys.ARM64:
-			ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 68+2)
-			ml.data[0] = 6                           /* thread type */
-			ml.data[1] = 68                          /* word count */
-			ml.data[2+64] = uint32(Entryvalue(ctxt)) /* start pc */
-			ml.data[2+64+1] = uint32(Entryvalue(ctxt) >> 32)
-
-		case sys.I386:
-			ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 16+2)
-			ml.data[0] = 1                           /* thread type */
-			ml.data[1] = 16                          /* word count */
-			ml.data[2+10] = uint32(Entryvalue(ctxt)) /* start pc */
-		}
-	}
-
-	if !*FlagD {
-		// must match domacholink below
-		s1 := ctxt.Syms.Lookup(".machosymtab", 0)
-		s2 := ctxt.Syms.Lookup(".linkedit.plt", 0)
-		s3 := ctxt.Syms.Lookup(".linkedit.got", 0)
-		s4 := ctxt.Syms.Lookup(".machosymstr", 0)
-
-		if ctxt.LinkMode != LinkExternal {
-			ms := newMachoSeg("__LINKEDIT", 0)
-			ms.vaddr = uint64(va) + uint64(v) + uint64(Rnd(int64(Segdata.Length), int64(*FlagRound)))
-			ms.vsize = uint64(s1.Size) + uint64(s2.Size) + uint64(s3.Size) + uint64(s4.Size)
-			ms.fileoffset = uint64(linkoff)
-			ms.filesize = ms.vsize
-			ms.prot1 = 7
-			ms.prot2 = 3
-		}
-
-		ml := newMachoLoad(ctxt.Arch, LC_SYMTAB, 4)
-		ml.data[0] = uint32(linkoff)                               /* symoff */
-		ml.data[1] = uint32(nsortsym)                              /* nsyms */
-		ml.data[2] = uint32(linkoff + s1.Size + s2.Size + s3.Size) /* stroff */
-		ml.data[3] = uint32(s4.Size)                               /* strsize */
-
-		machodysymtab(ctxt)
-
-		if ctxt.LinkMode != LinkExternal {
-			ml := newMachoLoad(ctxt.Arch, LC_LOAD_DYLINKER, 6)
-			ml.data[0] = 12 /* offset to string */
-			stringtouint32(ml.data[1:], "/usr/lib/dyld")
-
-			for _, lib := range dylib {
-				ml = newMachoLoad(ctxt.Arch, LC_LOAD_DYLIB, 4+(uint32(len(lib))+1+7)/8*2)
-				ml.data[0] = 24 /* offset of string from beginning of load */
-				ml.data[1] = 0  /* time stamp */
-				ml.data[2] = 0  /* version */
-				ml.data[3] = 0  /* compatibility version */
-				stringtouint32(ml.data[4:], lib)
-			}
-		}
-	}
-
-	a := machowrite(ctxt.Arch, ctxt.Out, ctxt.LinkMode)
-	if int32(a) > HEADR {
-		Exitf("HEADR too small: %d > %d", a, HEADR)
-	}
-}
-
-func symkind(s *sym.Symbol) int {
-	if s.Type == sym.SDYNIMPORT {
-		return SymKindUndef
-	}
-	if s.Attr.CgoExport() {
-		return SymKindExtdef
-	}
-	return SymKindLocal
-}
-
-func addsym(ctxt *Link, s *sym.Symbol, name string, type_ SymbolType, addr int64, gotype *sym.Symbol) {
-	if s == nil {
-		return
-	}
-
-	switch type_ {
-	default:
-		return
-
-	case DataSym, BSSSym, TextSym:
-		break
-	}
-
-	if sortsym != nil {
-		sortsym[nsortsym] = s
-		nkind[symkind(s)]++
-	}
-
-	nsortsym++
-}
-
-type machoscmp []*sym.Symbol
-
-func (x machoscmp) Len() int {
-	return len(x)
-}
-
-func (x machoscmp) Swap(i, j int) {
-	x[i], x[j] = x[j], x[i]
-}
-
-func (x machoscmp) Less(i, j int) bool {
-	s1 := x[i]
-	s2 := x[j]
-
-	k1 := symkind(s1)
-	k2 := symkind(s2)
-	if k1 != k2 {
-		return k1 < k2
-	}
-
-	return s1.Extname() < s2.Extname()
-}
-
-func machogenasmsym(ctxt *Link) {
-	genasmsym(ctxt, addsym)
-	for _, s := range ctxt.Syms.Allsym {
-		// Some 64-bit functions have a "$INODE64" or "$INODE64$UNIX2003" suffix.
-		if s.Type == sym.SDYNIMPORT && s.Dynimplib() == "/usr/lib/libSystem.B.dylib" {
-			// But only on macOS.
-			if machoPlatform == PLATFORM_MACOS {
-				switch n := s.Extname(); n {
-				case "fdopendir":
-					switch objabi.GOARCH {
-					case "amd64":
-						s.SetExtname(n + "$INODE64")
-					case "386":
-						s.SetExtname(n + "$INODE64$UNIX2003")
-					}
-				case "readdir_r", "getfsstat":
-					switch objabi.GOARCH {
-					case "amd64", "386":
-						s.SetExtname(n + "$INODE64")
-					}
-				}
-			}
-		}
-
-		if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ || s.Type == sym.SUNDEFEXT {
-			if s.Attr.Reachable() {
-				addsym(ctxt, s, "", DataSym, 0, nil)
-			}
-		}
-	}
-}
-
-func machosymorder(ctxt *Link) {
-	// On Mac OS X Mountain Lion, we must sort exported symbols
-	// So we sort them here and pre-allocate dynid for them
-	// See https://golang.org/issue/4029
-	for i := range dynexp {
-		dynexp[i].Attr |= sym.AttrReachable
-	}
-	machogenasmsym(ctxt)
-	sortsym = make([]*sym.Symbol, nsortsym)
-	nsortsym = 0
-	machogenasmsym(ctxt)
-	sort.Sort(machoscmp(sortsym[:nsortsym]))
-	for i := 0; i < nsortsym; i++ {
-		sortsym[i].Dynid = int32(i)
-	}
-}
-
-// machoShouldExport reports whether a symbol needs to be exported.
-//
-// When dynamically linking, all non-local variables and plugin-exported
-// symbols need to be exported.
-func machoShouldExport(ctxt *Link, s *sym.Symbol) bool {
-	if !ctxt.DynlinkingGo() || s.Attr.Local() {
-		return false
-	}
-	if ctxt.BuildMode == BuildModePlugin && strings.HasPrefix(s.Extname(), objabi.PathToPrefix(*flagPluginPath)) {
-		return true
-	}
-	if strings.HasPrefix(s.Name, "go.itab.") {
-		return true
-	}
-	if strings.HasPrefix(s.Name, "type.") && !strings.HasPrefix(s.Name, "type..") {
-		// reduce runtime typemap pressure, but do not
-		// export alg functions (type..*), as these
-		// appear in pclntable.
-		return true
-	}
-	if strings.HasPrefix(s.Name, "go.link.pkghash") {
-		return true
-	}
-	return s.Type >= sym.SFirstWritable // only writable sections
-}
-
-func machosymtab(ctxt *Link) {
-	symtab := ctxt.Syms.Lookup(".machosymtab", 0)
-	symstr := ctxt.Syms.Lookup(".machosymstr", 0)
-
-	for i := 0; i < nsortsym; i++ {
-		s := sortsym[i]
-		symtab.AddUint32(ctxt.Arch, uint32(symstr.Size))
-
-		export := machoShouldExport(ctxt, s)
-		isGoSymbol := strings.Contains(s.Extname(), ".")
-
-		// In normal buildmodes, only add _ to C symbols, as
-		// Go symbols have dot in the name.
-		//
-		// Do not export C symbols in plugins, as runtime C
-		// symbols like crosscall2 are in pclntab and end up
-		// pointing at the host binary, breaking unwinding.
-		// See Issue #18190.
-		cexport := !isGoSymbol && (ctxt.BuildMode != BuildModePlugin || onlycsymbol(s))
-		if cexport || export || isGoSymbol {
-			symstr.AddUint8('_')
-		}
-
-		// replace "·" as ".", because DTrace cannot handle it.
-		Addstring(symstr, strings.Replace(s.Extname(), "·", ".", -1))
-
-		if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ || s.Type == sym.SUNDEFEXT {
-			symtab.AddUint8(0x01)                             // type N_EXT, external symbol
-			symtab.AddUint8(0)                                // no section
-			symtab.AddUint16(ctxt.Arch, 0)                    // desc
-			symtab.AddUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize) // no value
-		} else {
-			if s.Attr.CgoExport() || export {
-				symtab.AddUint8(0x0f)
-			} else {
-				symtab.AddUint8(0x0e)
-			}
-			o := s
-			for o.Outer != nil {
-				o = o.Outer
-			}
-			if o.Sect == nil {
-				Errorf(s, "missing section for symbol")
-				symtab.AddUint8(0)
-			} else {
-				symtab.AddUint8(uint8(o.Sect.Extnum))
-			}
-			symtab.AddUint16(ctxt.Arch, 0) // desc
-			symtab.AddUintXX(ctxt.Arch, uint64(Symaddr(s)), ctxt.Arch.PtrSize)
-		}
-	}
-}
-
-func machodysymtab(ctxt *Link) {
-	ml := newMachoLoad(ctxt.Arch, LC_DYSYMTAB, 18)
-
-	n := 0
-	ml.data[0] = uint32(n)                   /* ilocalsym */
-	ml.data[1] = uint32(nkind[SymKindLocal]) /* nlocalsym */
-	n += nkind[SymKindLocal]
-
-	ml.data[2] = uint32(n)                    /* iextdefsym */
-	ml.data[3] = uint32(nkind[SymKindExtdef]) /* nextdefsym */
-	n += nkind[SymKindExtdef]
-
-	ml.data[4] = uint32(n)                   /* iundefsym */
-	ml.data[5] = uint32(nkind[SymKindUndef]) /* nundefsym */
-
-	ml.data[6] = 0  /* tocoffset */
-	ml.data[7] = 0  /* ntoc */
-	ml.data[8] = 0  /* modtaboff */
-	ml.data[9] = 0  /* nmodtab */
-	ml.data[10] = 0 /* extrefsymoff */
-	ml.data[11] = 0 /* nextrefsyms */
-
-	// must match domacholink below
-	s1 := ctxt.Syms.Lookup(".machosymtab", 0)
-
-	s2 := ctxt.Syms.Lookup(".linkedit.plt", 0)
-	s3 := ctxt.Syms.Lookup(".linkedit.got", 0)
-	ml.data[12] = uint32(linkoff + s1.Size)       /* indirectsymoff */
-	ml.data[13] = uint32((s2.Size + s3.Size) / 4) /* nindirectsyms */
-
-	ml.data[14] = 0 /* extreloff */
-	ml.data[15] = 0 /* nextrel */
-	ml.data[16] = 0 /* locreloff */
-	ml.data[17] = 0 /* nlocrel */
-}
-
-func Domacholink(ctxt *Link) int64 {
-	machosymtab(ctxt)
-
-	// write data that will be linkedit section
-	s1 := ctxt.Syms.Lookup(".machosymtab", 0)
-
-	s2 := ctxt.Syms.Lookup(".linkedit.plt", 0)
-	s3 := ctxt.Syms.Lookup(".linkedit.got", 0)
-	s4 := ctxt.Syms.Lookup(".machosymstr", 0)
-
-	// Force the linkedit section to end on a 16-byte
-	// boundary. This allows pure (non-cgo) Go binaries
-	// to be code signed correctly.
-	//
-	// Apple's codesign_allocate (a helper utility for
-	// the codesign utility) can do this fine itself if
-	// it is run on a dynamic Mach-O binary. However,
-	// when it is run on a pure (non-cgo) Go binary, where
-	// the linkedit section is mostly empty, it fails to
-	// account for the extra padding that it itself adds
-	// when adding the LC_CODE_SIGNATURE load command
-	// (which must be aligned on a 16-byte boundary).
-	//
-	// By forcing the linkedit section to end on a 16-byte
-	// boundary, codesign_allocate will not need to apply
-	// any alignment padding itself, working around the
-	// issue.
-	for s4.Size%16 != 0 {
-		s4.AddUint8(0)
-	}
-
-	size := int(s1.Size + s2.Size + s3.Size + s4.Size)
-
-	if size > 0 {
-		linkoff = Rnd(int64(uint64(HEADR)+Segtext.Length), int64(*FlagRound)) + Rnd(int64(Segdata.Filelen), int64(*FlagRound)) + Rnd(int64(Segdwarf.Filelen), int64(*FlagRound))
-		ctxt.Out.SeekSet(linkoff)
-
-		ctxt.Out.Write(s1.P[:s1.Size])
-		ctxt.Out.Write(s2.P[:s2.Size])
-		ctxt.Out.Write(s3.P[:s3.Size])
-		ctxt.Out.Write(s4.P[:s4.Size])
-	}
-
-	return Rnd(int64(size), int64(*FlagRound))
-}
-
-func machorelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) {
-	// If main section has no bits, nothing to relocate.
-	if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
-		return
-	}
-
-	sect.Reloff = uint64(ctxt.Out.Offset())
-	for i, s := range syms {
-		if !s.Attr.Reachable() {
-			continue
-		}
-		if uint64(s.Value) >= sect.Vaddr {
-			syms = syms[i:]
-			break
-		}
-	}
-
-	eaddr := int32(sect.Vaddr + sect.Length)
-	for _, s := range syms {
-		if !s.Attr.Reachable() {
-			continue
-		}
-		if s.Value >= int64(eaddr) {
-			break
-		}
-		for ri := range s.R {
-			r := &s.R[ri]
-			if r.Done {
-				continue
-			}
-			if r.Xsym == nil {
-				Errorf(s, "missing xsym in relocation")
-				continue
-			}
-			if !r.Xsym.Attr.Reachable() {
-				Errorf(s, "unreachable reloc %d (%s) target %v", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Xsym.Name)
-			}
-			if !thearch.Machoreloc1(ctxt.Arch, ctxt.Out, s, r, int64(uint64(s.Value+int64(r.Off))-sect.Vaddr)) {
-				Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name)
-			}
-		}
-	}
-
-	sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
-}
-
-func Machoemitreloc(ctxt *Link) {
-	for ctxt.Out.Offset()&7 != 0 {
-		ctxt.Out.Write8(0)
-	}
-
-	machorelocsect(ctxt, Segtext.Sections[0], ctxt.Textp)
-	for _, sect := range Segtext.Sections[1:] {
-		machorelocsect(ctxt, sect, datap)
-	}
-	for _, sect := range Segdata.Sections {
-		machorelocsect(ctxt, sect, datap)
-	}
-	for _, sect := range Segdwarf.Sections {
-		machorelocsect(ctxt, sect, dwarfp)
-	}
-}
-
-// hostobjMachoPlatform returns the first platform load command found
-// in the host object, if any.
-func hostobjMachoPlatform(h *Hostobj) (*MachoPlatformLoad, error) {
-	f, err := os.Open(h.file)
-	if err != nil {
-		return nil, fmt.Errorf("%s: failed to open host object: %v\n", h.file, err)
-	}
-	defer f.Close()
-	sr := io.NewSectionReader(f, h.off, h.length)
-	m, err := macho.NewFile(sr)
-	if err != nil {
-		// Not a valid Mach-O file.
-		return nil, nil
-	}
-	return peekMachoPlatform(m)
-}
-
-// peekMachoPlatform returns the first LC_VERSION_MIN_* or LC_BUILD_VERSION
-// load command found in the Mach-O file, if any.
-func peekMachoPlatform(m *macho.File) (*MachoPlatformLoad, error) {
-	for _, cmd := range m.Loads {
-		raw := cmd.Raw()
-		ml := MachoLoad{
-			type_: m.ByteOrder.Uint32(raw),
-		}
-		// Skip the type and command length.
-		data := raw[8:]
-		var p MachoPlatform
-		switch ml.type_ {
-		case LC_VERSION_MIN_IPHONEOS:
-			p = PLATFORM_IOS
-		case LC_VERSION_MIN_MACOSX:
-			p = PLATFORM_MACOS
-		case LC_VERSION_MIN_WATCHOS:
-			p = PLATFORM_WATCHOS
-		case LC_VERSION_MIN_TVOS:
-			p = PLATFORM_TVOS
-		case LC_BUILD_VERSION:
-			p = MachoPlatform(m.ByteOrder.Uint32(data))
-		default:
-			continue
-		}
-		ml.data = make([]uint32, len(data)/4)
-		r := bytes.NewReader(data)
-		if err := binary.Read(r, m.ByteOrder, &ml.data); err != nil {
-			return nil, err
-		}
-		return &MachoPlatformLoad{
-			platform: p,
-			cmd:      ml,
-		}, nil
-	}
-	return nil, nil
-}
diff --git a/src/cmd/oldlink/internal/ld/macho_combine_dwarf.go b/src/cmd/oldlink/internal/ld/macho_combine_dwarf.go
deleted file mode 100644
index 9d9f916..0000000
--- a/src/cmd/oldlink/internal/ld/macho_combine_dwarf.go
+++ /dev/null
@@ -1,462 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ld
-
-import (
-	"bytes"
-	"compress/zlib"
-	"debug/macho"
-	"encoding/binary"
-	"fmt"
-	"io"
-	"os"
-	"reflect"
-	"unsafe"
-)
-
-const (
-	pageAlign = 12 // 4096 = 1 << 12
-)
-
-type loadCmd struct {
-	Cmd macho.LoadCmd
-	Len uint32
-}
-
-type dyldInfoCmd struct {
-	Cmd                      macho.LoadCmd
-	Len                      uint32
-	RebaseOff, RebaseLen     uint32
-	BindOff, BindLen         uint32
-	WeakBindOff, WeakBindLen uint32
-	LazyBindOff, LazyBindLen uint32
-	ExportOff, ExportLen     uint32
-}
-
-type linkEditDataCmd struct {
-	Cmd              macho.LoadCmd
-	Len              uint32
-	DataOff, DataLen uint32
-}
-
-type encryptionInfoCmd struct {
-	Cmd                macho.LoadCmd
-	Len                uint32
-	CryptOff, CryptLen uint32
-	CryptId            uint32
-}
-
-type loadCmdReader struct {
-	offset, next int64
-	f            *os.File
-	order        binary.ByteOrder
-}
-
-func (r *loadCmdReader) Next() (loadCmd, error) {
-	var cmd loadCmd
-
-	r.offset = r.next
-	if _, err := r.f.Seek(r.offset, 0); err != nil {
-		return cmd, err
-	}
-	if err := binary.Read(r.f, r.order, &cmd); err != nil {
-		return cmd, err
-	}
-	r.next = r.offset + int64(cmd.Len)
-	return cmd, nil
-}
-
-func (r loadCmdReader) ReadAt(offset int64, data interface{}) error {
-	if _, err := r.f.Seek(r.offset+offset, 0); err != nil {
-		return err
-	}
-	return binary.Read(r.f, r.order, data)
-}
-
-func (r loadCmdReader) WriteAt(offset int64, data interface{}) error {
-	if _, err := r.f.Seek(r.offset+offset, 0); err != nil {
-		return err
-	}
-	return binary.Write(r.f, r.order, data)
-}
-
-// machoCombineDwarf merges dwarf info generated by dsymutil into a macho executable.
-//
-// With internal linking, DWARF is embedded into the executable, this lets us do the
-// same for external linking.
-// exef is the file of the executable with no DWARF. It must have enough room in the macho
-// header to add the DWARF sections. (Use ld's -headerpad option)
-// exem is the macho representation of exef.
-// dsym is the path to the macho file containing DWARF from dsymutil.
-// outexe is the path where the combined executable should be saved.
-func machoCombineDwarf(ctxt *Link, exef *os.File, exem *macho.File, dsym, outexe string) error {
-	dwarff, err := os.Open(dsym)
-	if err != nil {
-		return err
-	}
-	defer dwarff.Close()
-	outf, err := os.OpenFile(outexe, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
-	if err != nil {
-		return err
-	}
-	defer outf.Close()
-	dwarfm, err := macho.NewFile(dwarff)
-	if err != nil {
-		return err
-	}
-	defer dwarfm.Close()
-
-	// The string table needs to be the last thing in the file
-	// for code signing to work. So we'll need to move the
-	// linkedit section, but all the others can be copied directly.
-	linkseg := exem.Segment("__LINKEDIT")
-	if linkseg == nil {
-		return fmt.Errorf("missing __LINKEDIT segment")
-	}
-
-	if _, err := exef.Seek(0, 0); err != nil {
-		return err
-	}
-	if _, err := io.CopyN(outf, exef, int64(linkseg.Offset)); err != nil {
-		return err
-	}
-
-	realdwarf := dwarfm.Segment("__DWARF")
-	if realdwarf == nil {
-		return fmt.Errorf("missing __DWARF segment")
-	}
-
-	// Try to compress the DWARF sections. This includes some Apple
-	// proprietary sections like __apple_types.
-	compressedSects, compressedBytes, err := machoCompressSections(ctxt, dwarfm)
-	if err != nil {
-		return err
-	}
-
-	// Now copy the dwarf data into the output.
-	// Kernel requires all loaded segments to be page-aligned in the file,
-	// even though we mark this one as being 0 bytes of virtual address space.
-	dwarfstart := machoCalcStart(realdwarf.Offset, linkseg.Offset, pageAlign)
-	if _, err := outf.Seek(dwarfstart, 0); err != nil {
-		return err
-	}
-
-	if _, err := dwarff.Seek(int64(realdwarf.Offset), 0); err != nil {
-		return err
-	}
-
-	// Write out the compressed sections, or the originals if we gave up
-	// on compressing them.
-	var dwarfsize uint64
-	if compressedBytes != nil {
-		dwarfsize = uint64(len(compressedBytes))
-		if _, err := outf.Write(compressedBytes); err != nil {
-			return err
-		}
-	} else {
-		if _, err := io.CopyN(outf, dwarff, int64(realdwarf.Filesz)); err != nil {
-			return err
-		}
-		dwarfsize = realdwarf.Filesz
-	}
-
-	// And finally the linkedit section.
-	if _, err := exef.Seek(int64(linkseg.Offset), 0); err != nil {
-		return err
-	}
-	linkstart := machoCalcStart(linkseg.Offset, uint64(dwarfstart)+dwarfsize, pageAlign)
-	if _, err := outf.Seek(linkstart, 0); err != nil {
-		return err
-	}
-	if _, err := io.Copy(outf, exef); err != nil {
-		return err
-	}
-
-	// Now we need to update the headers.
-	textsect := exem.Section("__text")
-	if textsect == nil {
-		return fmt.Errorf("missing __text section")
-	}
-
-	cmdOffset := unsafe.Sizeof(exem.FileHeader)
-	if is64bit := exem.Magic == macho.Magic64; is64bit {
-		// mach_header_64 has one extra uint32.
-		cmdOffset += unsafe.Sizeof(exem.Magic)
-	}
-	dwarfCmdOffset := uint32(cmdOffset) + exem.FileHeader.Cmdsz
-	availablePadding := textsect.Offset - dwarfCmdOffset
-	if availablePadding < realdwarf.Len {
-		return fmt.Errorf("no room to add dwarf info. Need at least %d padding bytes, found %d", realdwarf.Len, availablePadding)
-	}
-	// First, copy the dwarf load command into the header. It will be
-	// updated later with new offsets and lengths as necessary.
-	if _, err := outf.Seek(int64(dwarfCmdOffset), 0); err != nil {
-		return err
-	}
-	if _, err := io.CopyN(outf, bytes.NewReader(realdwarf.Raw()), int64(realdwarf.Len)); err != nil {
-		return err
-	}
-	if _, err := outf.Seek(int64(unsafe.Offsetof(exem.FileHeader.Ncmd)), 0); err != nil {
-		return err
-	}
-	if err := binary.Write(outf, exem.ByteOrder, exem.Ncmd+1); err != nil {
-		return err
-	}
-	if err := binary.Write(outf, exem.ByteOrder, exem.Cmdsz+realdwarf.Len); err != nil {
-		return err
-	}
-
-	reader := loadCmdReader{next: int64(cmdOffset), f: outf, order: exem.ByteOrder}
-	for i := uint32(0); i < exem.Ncmd; i++ {
-		cmd, err := reader.Next()
-		if err != nil {
-			return err
-		}
-		linkoffset := uint64(linkstart) - linkseg.Offset
-		switch cmd.Cmd {
-		case macho.LoadCmdSegment64:
-			err = machoUpdateSegment(reader, linkseg, linkoffset, &macho.Segment64{}, &macho.Section64{})
-		case macho.LoadCmdSegment:
-			err = machoUpdateSegment(reader, linkseg, linkoffset, &macho.Segment32{}, &macho.Section32{})
-		case LC_DYLD_INFO, LC_DYLD_INFO_ONLY:
-			err = machoUpdateLoadCommand(reader, linkseg, linkoffset, &dyldInfoCmd{}, "RebaseOff", "BindOff", "WeakBindOff", "LazyBindOff", "ExportOff")
-		case macho.LoadCmdSymtab:
-			err = machoUpdateLoadCommand(reader, linkseg, linkoffset, &macho.SymtabCmd{}, "Symoff", "Stroff")
-		case macho.LoadCmdDysymtab:
-			err = machoUpdateLoadCommand(reader, linkseg, linkoffset, &macho.DysymtabCmd{}, "Tocoffset", "Modtaboff", "Extrefsymoff", "Indirectsymoff", "Extreloff", "Locreloff")
-		case LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS:
-			err = machoUpdateLoadCommand(reader, linkseg, linkoffset, &linkEditDataCmd{}, "DataOff")
-		case LC_ENCRYPTION_INFO, LC_ENCRYPTION_INFO_64:
-			err = machoUpdateLoadCommand(reader, linkseg, linkoffset, &encryptionInfoCmd{}, "CryptOff")
-		case macho.LoadCmdDylib, macho.LoadCmdThread, macho.LoadCmdUnixThread, LC_PREBOUND_DYLIB, LC_UUID, LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS, LC_SOURCE_VERSION, LC_MAIN, LC_LOAD_DYLINKER, LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB, LC_RPATH, LC_ID_DYLIB, LC_SYMSEG, LC_LOADFVMLIB, LC_IDFVMLIB, LC_IDENT, LC_FVMFILE, LC_PREPAGE, LC_ID_DYLINKER, LC_ROUTINES, LC_SUB_FRAMEWORK, LC_SUB_UMBRELLA, LC_SUB_CLIENT, LC_SUB_LIBRARY, LC_TWOLEVEL_HINTS, LC_PREBIND_CKSUM, LC_ROUTINES_64, LC_LAZY_LOAD_DYLIB, LC_LOAD_UPWARD_DYLIB, LC_DYLD_ENVIRONMENT, LC_LINKER_OPTION, LC_LINKER_OPTIMIZATION_HINT, LC_VERSION_MIN_TVOS, LC_VERSION_MIN_WATCHOS, LC_VERSION_NOTE, LC_BUILD_VERSION:
-			// Nothing to update
-		default:
-			err = fmt.Errorf("unknown load command 0x%x (%s)", int(cmd.Cmd), cmd.Cmd)
-		}
-		if err != nil {
-			return err
-		}
-	}
-	// Do the final update of the DWARF segment's load command.
-	return machoUpdateDwarfHeader(&reader, compressedSects, dwarfsize, dwarfstart, realdwarf)
-}
-
-// machoCompressSections tries to compress the DWARF segments in dwarfm,
-// returning the updated sections and segment contents, nils if the sections
-// weren't compressed, or an error if there was a problem reading dwarfm.
-func machoCompressSections(ctxt *Link, dwarfm *macho.File) ([]*macho.Section, []byte, error) {
-	if !ctxt.compressDWARF {
-		return nil, nil, nil
-	}
-
-	dwarfseg := dwarfm.Segment("__DWARF")
-	var sects []*macho.Section
-	var buf bytes.Buffer
-
-	for _, sect := range dwarfm.Sections {
-		if sect.Seg != "__DWARF" {
-			continue
-		}
-
-		// As of writing, there are no relocations in dsymutil's output
-		// so there's no point in worrying about them. Bail out if that
-		// changes.
-		if sect.Nreloc != 0 {
-			return nil, nil, nil
-		}
-
-		data, err := sect.Data()
-		if err != nil {
-			return nil, nil, err
-		}
-
-		compressed, contents, err := machoCompressSection(data)
-		if err != nil {
-			return nil, nil, err
-		}
-
-		newSec := *sect
-		newSec.Offset = uint32(dwarfseg.Offset) + uint32(buf.Len())
-		newSec.Addr = dwarfseg.Addr + uint64(buf.Len())
-		if compressed {
-			newSec.Name = "__z" + sect.Name[2:]
-			newSec.Size = uint64(len(contents))
-		}
-		sects = append(sects, &newSec)
-		buf.Write(contents)
-	}
-	return sects, buf.Bytes(), nil
-}
-
-// machoCompressSection compresses secBytes if it results in less data.
-func machoCompressSection(sectBytes []byte) (compressed bool, contents []byte, err error) {
-	var buf bytes.Buffer
-	buf.WriteString("ZLIB")
-	var sizeBytes [8]byte
-	binary.BigEndian.PutUint64(sizeBytes[:], uint64(len(sectBytes)))
-	buf.Write(sizeBytes[:])
-
-	z := zlib.NewWriter(&buf)
-	if _, err := z.Write(sectBytes); err != nil {
-		return false, nil, err
-	}
-	if err := z.Close(); err != nil {
-		return false, nil, err
-	}
-	if buf.Len() >= len(sectBytes) {
-		return false, sectBytes, nil
-	}
-	return true, buf.Bytes(), nil
-}
-
-// machoUpdateSegment updates the load command for a moved segment.
-// Only the linkedit segment should move, and it should have 0 sections.
-// seg should be a macho.Segment32 or macho.Segment64 as appropriate.
-// sect should be a macho.Section32 or macho.Section64 as appropriate.
-func machoUpdateSegment(r loadCmdReader, linkseg *macho.Segment, linkoffset uint64, seg, sect interface{}) error {
-	if err := r.ReadAt(0, seg); err != nil {
-		return err
-	}
-	segValue := reflect.ValueOf(seg)
-	offset := reflect.Indirect(segValue).FieldByName("Offset")
-
-	// Only the linkedit segment moved, anything before that is fine.
-	if offset.Uint() < linkseg.Offset {
-		return nil
-	}
-	offset.SetUint(offset.Uint() + linkoffset)
-	if err := r.WriteAt(0, seg); err != nil {
-		return err
-	}
-	// There shouldn't be any sections, but just to make sure...
-	return machoUpdateSections(r, segValue, reflect.ValueOf(sect), linkoffset, nil)
-}
-
-func machoUpdateSections(r loadCmdReader, seg, sect reflect.Value, deltaOffset uint64, compressedSects []*macho.Section) error {
-	iseg := reflect.Indirect(seg)
-	nsect := iseg.FieldByName("Nsect").Uint()
-	if nsect == 0 {
-		return nil
-	}
-	sectOffset := int64(iseg.Type().Size())
-
-	isect := reflect.Indirect(sect)
-	offsetField := isect.FieldByName("Offset")
-	reloffField := isect.FieldByName("Reloff")
-	addrField := isect.FieldByName("Addr")
-	nameField := isect.FieldByName("Name")
-	sizeField := isect.FieldByName("Size")
-	sectSize := int64(isect.Type().Size())
-	for i := uint64(0); i < nsect; i++ {
-		if err := r.ReadAt(sectOffset, sect.Interface()); err != nil {
-			return err
-		}
-		if compressedSects != nil {
-			cSect := compressedSects[i]
-			var name [16]byte
-			copy(name[:], []byte(cSect.Name))
-			nameField.Set(reflect.ValueOf(name))
-			sizeField.SetUint(cSect.Size)
-			if cSect.Offset != 0 {
-				offsetField.SetUint(uint64(cSect.Offset) + deltaOffset)
-			}
-			if cSect.Addr != 0 {
-				addrField.SetUint(cSect.Addr)
-			}
-		} else {
-			if offsetField.Uint() != 0 {
-				offsetField.SetUint(offsetField.Uint() + deltaOffset)
-			}
-			if reloffField.Uint() != 0 {
-				reloffField.SetUint(reloffField.Uint() + deltaOffset)
-			}
-			if addrField.Uint() != 0 {
-				addrField.SetUint(addrField.Uint())
-			}
-		}
-		if err := r.WriteAt(sectOffset, sect.Interface()); err != nil {
-			return err
-		}
-		sectOffset += sectSize
-	}
-	return nil
-}
-
-// machoUpdateDwarfHeader updates the DWARF segment load command.
-func machoUpdateDwarfHeader(r *loadCmdReader, compressedSects []*macho.Section, dwarfsize uint64, dwarfstart int64, realdwarf *macho.Segment) error {
-	var seg, sect interface{}
-	cmd, err := r.Next()
-	if err != nil {
-		return err
-	}
-	if cmd.Cmd == macho.LoadCmdSegment64 {
-		seg = new(macho.Segment64)
-		sect = new(macho.Section64)
-	} else {
-		seg = new(macho.Segment32)
-		sect = new(macho.Section32)
-	}
-	if err := r.ReadAt(0, seg); err != nil {
-		return err
-	}
-	segv := reflect.ValueOf(seg).Elem()
-	segv.FieldByName("Offset").SetUint(uint64(dwarfstart))
-
-	if compressedSects != nil {
-		var segSize uint64
-		for _, newSect := range compressedSects {
-			segSize += newSect.Size
-		}
-		segv.FieldByName("Filesz").SetUint(segSize)
-	} else {
-		segv.FieldByName("Filesz").SetUint(dwarfsize)
-	}
-
-	// We want the DWARF segment to be considered non-loadable, so
-	// force vmaddr and vmsize to zero. In addition, set the initial
-	// protection to zero so as to make the dynamic loader happy,
-	// since otherwise it may complain that that the vm size and file
-	// size don't match for the segment. See issues 21647 and 32673
-	// for more context. Also useful to refer to the Apple dynamic
-	// loader source, specifically ImageLoaderMachO::sniffLoadCommands
-	// in ImageLoaderMachO.cpp (various versions can be found online, see
-	// https://opensource.apple.com/source/dyld/dyld-519.2.2/src/ImageLoaderMachO.cpp.auto.html
-	// as one example).
-	segv.FieldByName("Addr").SetUint(0)
-	segv.FieldByName("Memsz").SetUint(0)
-	segv.FieldByName("Prot").SetUint(0)
-
-	if err := r.WriteAt(0, seg); err != nil {
-		return err
-	}
-	return machoUpdateSections(*r, segv, reflect.ValueOf(sect), uint64(dwarfstart)-realdwarf.Offset, compressedSects)
-}
-
-func machoUpdateLoadCommand(r loadCmdReader, linkseg *macho.Segment, linkoffset uint64, cmd interface{}, fields ...string) error {
-	if err := r.ReadAt(0, cmd); err != nil {
-		return err
-	}
-	value := reflect.Indirect(reflect.ValueOf(cmd))
-
-	for _, name := range fields {
-		field := value.FieldByName(name)
-		if fieldval := field.Uint(); fieldval >= linkseg.Offset {
-			field.SetUint(fieldval + linkoffset)
-		}
-	}
-	if err := r.WriteAt(0, cmd); err != nil {
-		return err
-	}
-	return nil
-}
-
-func machoCalcStart(origAddr, newAddr uint64, alignExp uint32) int64 {
-	align := uint64(1 << alignExp)
-	origMod, newMod := origAddr%align, newAddr%align
-	if origMod == newMod {
-		return int64(newAddr)
-	}
-	return int64(newAddr + align + origMod - newMod)
-}
diff --git a/src/cmd/oldlink/internal/ld/main.go b/src/cmd/oldlink/internal/ld/main.go
deleted file mode 100644
index f7f3700..0000000
--- a/src/cmd/oldlink/internal/ld/main.go
+++ /dev/null
@@ -1,338 +0,0 @@
-// Inferno utils/6l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ld
-
-import (
-	"bufio"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/sym"
-	"flag"
-	"log"
-	"os"
-	"runtime"
-	"runtime/pprof"
-	"strings"
-)
-
-var (
-	pkglistfornote []byte
-	windowsgui     bool // writes a "GUI binary" instead of a "console binary"
-	ownTmpDir      bool // set to true if tmp dir created by linker (e.g. no -tmpdir)
-)
-
-func init() {
-	flag.Var(&rpath, "r", "set the ELF dynamic linker search `path` to dir1:dir2:...")
-}
-
-// Flags used by the linker. The exported flags are used by the architecture-specific packages.
-var (
-	flagBuildid = flag.String("buildid", "", "record `id` as Go toolchain build id")
-
-	flagOutfile    = flag.String("o", "", "write output to `file`")
-	flagPluginPath = flag.String("pluginpath", "", "full path name for plugin")
-
-	flagInstallSuffix = flag.String("installsuffix", "", "set package directory `suffix`")
-	flagDumpDep       = flag.Bool("dumpdep", false, "dump symbol dependency graph")
-	flagRace          = flag.Bool("race", false, "enable race detector")
-	flagMsan          = flag.Bool("msan", false, "enable MSan interface")
-
-	flagFieldTrack = flag.String("k", "", "set field tracking `symbol`")
-	flagLibGCC     = flag.String("libgcc", "", "compiler support lib for internal linking; use \"none\" to disable")
-	flagTmpdir     = flag.String("tmpdir", "", "use `directory` for temporary files")
-
-	flagExtld      = flag.String("extld", "", "use `linker` when linking in external mode")
-	flagExtldflags = flag.String("extldflags", "", "pass `flags` to external linker")
-	flagExtar      = flag.String("extar", "", "archive program for buildmode=c-archive")
-
-	flagA           = flag.Bool("a", false, "disassemble output")
-	FlagC           = flag.Bool("c", false, "dump call graph")
-	FlagD           = flag.Bool("d", false, "disable dynamic executable")
-	flagF           = flag.Bool("f", false, "ignore version mismatch")
-	flagG           = flag.Bool("g", false, "disable go package data checks")
-	flagH           = flag.Bool("h", false, "halt on error")
-	flagN           = flag.Bool("n", false, "dump symbol table")
-	FlagS           = flag.Bool("s", false, "disable symbol table")
-	flagU           = flag.Bool("u", false, "reject unsafe packages")
-	FlagW           = flag.Bool("w", false, "disable DWARF generation")
-	Flag8           bool // use 64-bit addresses in symbol table
-	flagInterpreter = flag.String("I", "", "use `linker` as ELF dynamic linker")
-	FlagDebugTramp  = flag.Int("debugtramp", 0, "debug trampolines")
-	FlagStrictDups  = flag.Int("strictdups", 0, "sanity check duplicate symbol contents during object file reading (1=warn 2=err).")
-	flagNewobj      = flag.Bool("newobj", false, "use new object file format")
-
-	FlagRound       = flag.Int("R", -1, "set address rounding `quantum`")
-	FlagTextAddr    = flag.Int64("T", -1, "set text segment `address`")
-	flagEntrySymbol = flag.String("E", "", "set `entry` symbol name")
-
-	cpuprofile     = flag.String("cpuprofile", "", "write cpu profile to `file`")
-	memprofile     = flag.String("memprofile", "", "write memory profile to `file`")
-	memprofilerate = flag.Int64("memprofilerate", 0, "set runtime.MemProfileRate to `rate`")
-)
-
-// Main is the main entry point for the linker code.
-func Main(arch *sys.Arch, theArch Arch) {
-	thearch = theArch
-	ctxt := linknew(arch)
-	ctxt.Bso = bufio.NewWriter(os.Stdout)
-
-	// For testing behavior of go command when tools crash silently.
-	// Undocumented, not in standard flag parser to avoid
-	// exposing in usage message.
-	for _, arg := range os.Args {
-		if arg == "-crash_for_testing" {
-			os.Exit(2)
-		}
-	}
-
-	final := gorootFinal()
-	addstrdata1(ctxt, "runtime/internal/sys.DefaultGoroot="+final)
-	addstrdata1(ctxt, "cmd/internal/objabi.defaultGOROOT="+final)
-
-	// TODO(matloob): define these above and then check flag values here
-	if ctxt.Arch.Family == sys.AMD64 && objabi.GOOS == "plan9" {
-		flag.BoolVar(&Flag8, "8", false, "use 64-bit addresses in symbol table")
-	}
-	flagHeadType := flag.String("H", "", "set header `type`")
-	flag.BoolVar(&ctxt.linkShared, "linkshared", false, "link against installed Go shared libraries")
-	flag.Var(&ctxt.LinkMode, "linkmode", "set link `mode`")
-	flag.Var(&ctxt.BuildMode, "buildmode", "set build `mode`")
-	flag.BoolVar(&ctxt.compressDWARF, "compressdwarf", true, "compress DWARF if possible")
-	objabi.Flagfn1("B", "add an ELF NT_GNU_BUILD_ID `note` when using ELF", addbuildinfo)
-	objabi.Flagfn1("L", "add specified `directory` to library path", func(a string) { Lflag(ctxt, a) })
-	objabi.AddVersionFlag() // -V
-	objabi.Flagfn1("X", "add string value `definition` of the form importpath.name=value", func(s string) { addstrdata1(ctxt, s) })
-	objabi.Flagcount("v", "print link trace", &ctxt.Debugvlog)
-	objabi.Flagfn1("importcfg", "read import configuration from `file`", ctxt.readImportCfg)
-
-	objabi.Flagparse(usage)
-
-	switch *flagHeadType {
-	case "":
-	case "windowsgui":
-		ctxt.HeadType = objabi.Hwindows
-		windowsgui = true
-	default:
-		if err := ctxt.HeadType.Set(*flagHeadType); err != nil {
-			Errorf(nil, "%v", err)
-			usage()
-		}
-	}
-
-	if objabi.Fieldtrack_enabled != 0 {
-		ctxt.Reachparent = make(map[*sym.Symbol]*sym.Symbol)
-	}
-	checkStrictDups = *FlagStrictDups
-
-	startProfile()
-	if ctxt.BuildMode == BuildModeUnset {
-		ctxt.BuildMode = BuildModeExe
-	}
-
-	if ctxt.BuildMode != BuildModeShared && flag.NArg() != 1 {
-		usage()
-	}
-
-	if *flagOutfile == "" {
-		*flagOutfile = "a.out"
-		if ctxt.HeadType == objabi.Hwindows {
-			*flagOutfile += ".exe"
-		}
-	}
-
-	interpreter = *flagInterpreter
-
-	libinit(ctxt) // creates outfile
-
-	if ctxt.HeadType == objabi.Hunknown {
-		ctxt.HeadType.Set(objabi.GOOS)
-	}
-
-	ctxt.computeTLSOffset()
-	thearch.Archinit(ctxt)
-
-	if ctxt.linkShared && !ctxt.IsELF {
-		Exitf("-linkshared can only be used on elf systems")
-	}
-
-	if ctxt.Debugvlog != 0 {
-		ctxt.Logf("HEADER = -H%d -T0x%x -R0x%x\n", ctxt.HeadType, uint64(*FlagTextAddr), uint32(*FlagRound))
-	}
-
-	switch ctxt.BuildMode {
-	case BuildModeShared:
-		for i := 0; i < flag.NArg(); i++ {
-			arg := flag.Arg(i)
-			parts := strings.SplitN(arg, "=", 2)
-			var pkgpath, file string
-			if len(parts) == 1 {
-				pkgpath, file = "main", arg
-			} else {
-				pkgpath, file = parts[0], parts[1]
-			}
-			pkglistfornote = append(pkglistfornote, pkgpath...)
-			pkglistfornote = append(pkglistfornote, '\n')
-			addlibpath(ctxt, "command line", "command line", file, pkgpath, "")
-		}
-	case BuildModePlugin:
-		addlibpath(ctxt, "command line", "command line", flag.Arg(0), *flagPluginPath, "")
-	default:
-		addlibpath(ctxt, "command line", "command line", flag.Arg(0), "main", "")
-	}
-	ctxt.loadlib()
-
-	deadcode(ctxt)
-	if *flagNewobj {
-		ctxt.loadlibfull() // XXX do it here for now
-	}
-	ctxt.linksetup()
-	ctxt.dostrdata()
-
-	dwarfGenerateDebugInfo(ctxt)
-	if objabi.Fieldtrack_enabled != 0 {
-		fieldtrack(ctxt)
-	}
-	ctxt.mangleTypeSym()
-	ctxt.callgraph()
-
-	ctxt.doelf()
-	if ctxt.HeadType == objabi.Hdarwin {
-		ctxt.domacho()
-	}
-	ctxt.dostkcheck()
-	if ctxt.HeadType == objabi.Hwindows {
-		ctxt.dope()
-		ctxt.windynrelocsyms()
-	}
-	if ctxt.HeadType == objabi.Haix {
-		ctxt.doxcoff()
-	}
-
-	ctxt.addexport()
-	thearch.Gentext(ctxt) // trampolines, call stubs, etc.
-	ctxt.textbuildid()
-	ctxt.textaddress()
-	ctxt.pclntab()
-	ctxt.findfunctab()
-	ctxt.typelink()
-	ctxt.symtab()
-	ctxt.buildinfo()
-	ctxt.dodata()
-	order := ctxt.address()
-	dwarfcompress(ctxt)
-	filesize := ctxt.layout(order)
-
-	// Write out the output file.
-	// It is split into two parts (Asmb and Asmb2). The first
-	// part writes most of the content (sections and segments),
-	// for which we have computed the size and offset, in a
-	// mmap'd region. The second part writes more content, for
-	// which we don't know the size.
-	var outputMmapped bool
-	if ctxt.Arch.Family != sys.Wasm {
-		// Don't mmap if we're building for Wasm. Wasm file
-		// layout is very different so filesize is meaningless.
-		err := ctxt.Out.Mmap(filesize)
-		outputMmapped = err == nil
-	}
-	if outputMmapped {
-		// Asmb will redirect symbols to the output file mmap, and relocations
-		// will be applied directly there.
-		thearch.Asmb(ctxt)
-		ctxt.reloc()
-		ctxt.Out.Munmap()
-	} else {
-		// If we don't mmap, we need to apply relocations before
-		// writing out.
-		ctxt.reloc()
-		thearch.Asmb(ctxt)
-	}
-	thearch.Asmb2(ctxt)
-
-	ctxt.undef()
-	ctxt.hostlink()
-	if ctxt.Debugvlog != 0 {
-		ctxt.Logf("%d symbols\n", len(ctxt.Syms.Allsym))
-		ctxt.Logf("%d liveness data\n", liveness)
-	}
-	ctxt.Bso.Flush()
-	ctxt.archive()
-
-	errorexit()
-}
-
-type Rpath struct {
-	set bool
-	val string
-}
-
-func (r *Rpath) Set(val string) error {
-	r.set = true
-	r.val = val
-	return nil
-}
-
-func (r *Rpath) String() string {
-	return r.val
-}
-
-func startProfile() {
-	if *cpuprofile != "" {
-		f, err := os.Create(*cpuprofile)
-		if err != nil {
-			log.Fatalf("%v", err)
-		}
-		if err := pprof.StartCPUProfile(f); err != nil {
-			log.Fatalf("%v", err)
-		}
-		AtExit(pprof.StopCPUProfile)
-	}
-	if *memprofile != "" {
-		if *memprofilerate != 0 {
-			runtime.MemProfileRate = int(*memprofilerate)
-		}
-		f, err := os.Create(*memprofile)
-		if err != nil {
-			log.Fatalf("%v", err)
-		}
-		AtExit(func() {
-			// Profile all outstanding allocations.
-			runtime.GC()
-			// compilebench parses the memory profile to extract memstats,
-			// which are only written in the legacy pprof format.
-			// See golang.org/issue/18641 and runtime/pprof/pprof.go:writeHeap.
-			const writeLegacyFormat = 1
-			if err := pprof.Lookup("heap").WriteTo(f, writeLegacyFormat); err != nil {
-				log.Fatalf("%v", err)
-			}
-		})
-	}
-}
diff --git a/src/cmd/oldlink/internal/ld/outbuf.go b/src/cmd/oldlink/internal/ld/outbuf.go
deleted file mode 100644
index 596d239..0000000
--- a/src/cmd/oldlink/internal/ld/outbuf.go
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ld
-
-import (
-	"bufio"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/sym"
-	"encoding/binary"
-	"log"
-	"os"
-)
-
-// OutBuf is a buffered file writer.
-//
-// It is simlar to the Writer in cmd/internal/bio with a few small differences.
-//
-// First, it tracks the output architecture and uses it to provide
-// endian helpers.
-//
-// Second, it provides a very cheap offset counter that doesn't require
-// any system calls to read the value.
-//
-// It also mmaps the output file (if available). The intended usage is:
-// - Mmap the output file
-// - Write the content
-// - possibly apply any edits in the output buffer
-// - Munmap the output file
-// - possibly write more content to the file, which will not be edited later.
-type OutBuf struct {
-	arch   *sys.Arch
-	off    int64
-	w      *bufio.Writer
-	buf    []byte // backing store of mmap'd output file
-	f      *os.File
-	encbuf [8]byte // temp buffer used by WriteN methods
-}
-
-func (out *OutBuf) SeekSet(p int64) {
-	if p == out.off {
-		return
-	}
-	if out.buf == nil {
-		out.Flush()
-		if _, err := out.f.Seek(p, 0); err != nil {
-			Exitf("seeking to %d in %s: %v", p, out.f.Name(), err)
-		}
-	}
-	out.off = p
-}
-
-func (out *OutBuf) Offset() int64 {
-	return out.off
-}
-
-// Write writes the contents of v to the buffer.
-//
-// As Write is backed by a bufio.Writer, callers do not have
-// to explicitly handle the returned error as long as Flush is
-// eventually called.
-func (out *OutBuf) Write(v []byte) (int, error) {
-	if out.buf != nil {
-		n := copy(out.buf[out.off:], v)
-		out.off += int64(n)
-		return n, nil
-	}
-	n, err := out.w.Write(v)
-	out.off += int64(n)
-	return n, err
-}
-
-func (out *OutBuf) Write8(v uint8) {
-	if out.buf != nil {
-		out.buf[out.off] = v
-		out.off++
-		return
-	}
-	if err := out.w.WriteByte(v); err == nil {
-		out.off++
-	}
-}
-
-// WriteByte is an alias for Write8 to fulfill the io.ByteWriter interface.
-func (out *OutBuf) WriteByte(v byte) error {
-	out.Write8(v)
-	return nil
-}
-
-func (out *OutBuf) Write16(v uint16) {
-	out.arch.ByteOrder.PutUint16(out.encbuf[:], v)
-	out.Write(out.encbuf[:2])
-}
-
-func (out *OutBuf) Write32(v uint32) {
-	out.arch.ByteOrder.PutUint32(out.encbuf[:], v)
-	out.Write(out.encbuf[:4])
-}
-
-func (out *OutBuf) Write32b(v uint32) {
-	binary.BigEndian.PutUint32(out.encbuf[:], v)
-	out.Write(out.encbuf[:4])
-}
-
-func (out *OutBuf) Write64(v uint64) {
-	out.arch.ByteOrder.PutUint64(out.encbuf[:], v)
-	out.Write(out.encbuf[:8])
-}
-
-func (out *OutBuf) Write64b(v uint64) {
-	binary.BigEndian.PutUint64(out.encbuf[:], v)
-	out.Write(out.encbuf[:8])
-}
-
-func (out *OutBuf) WriteString(s string) {
-	if out.buf != nil {
-		n := copy(out.buf[out.off:], s)
-		if n != len(s) {
-			log.Fatalf("WriteString truncated. buffer size: %d, offset: %d, len(s)=%d", len(out.buf), out.off, len(s))
-		}
-		out.off += int64(n)
-		return
-	}
-	n, _ := out.w.WriteString(s)
-	out.off += int64(n)
-}
-
-// WriteStringN writes the first n bytes of s.
-// If n is larger than len(s) then it is padded with zero bytes.
-func (out *OutBuf) WriteStringN(s string, n int) {
-	out.WriteStringPad(s, n, zeros[:])
-}
-
-// WriteStringPad writes the first n bytes of s.
-// If n is larger than len(s) then it is padded with the bytes in pad (repeated as needed).
-func (out *OutBuf) WriteStringPad(s string, n int, pad []byte) {
-	if len(s) >= n {
-		out.WriteString(s[:n])
-	} else {
-		out.WriteString(s)
-		n -= len(s)
-		for n > len(pad) {
-			out.Write(pad)
-			n -= len(pad)
-
-		}
-		out.Write(pad[:n])
-	}
-}
-
-// WriteSym writes the content of a Symbol, then changes the Symbol's content
-// to point to the output buffer that we just wrote, so we can apply further
-// edit to the symbol content.
-// If the output file is not Mmap'd, just writes the content.
-func (out *OutBuf) WriteSym(s *sym.Symbol) {
-	if out.buf != nil {
-		start := out.off
-		out.Write(s.P)
-		s.P = out.buf[start:out.off]
-		s.Attr.Set(sym.AttrReadOnly, false)
-	} else {
-		out.Write(s.P)
-	}
-}
-
-func (out *OutBuf) Flush() {
-	var err error
-	if out.buf != nil {
-		err = out.Msync()
-	} else {
-		err = out.w.Flush()
-	}
-	if err != nil {
-		Exitf("flushing %s: %v", out.f.Name(), err)
-	}
-}
diff --git a/src/cmd/oldlink/internal/ld/outbuf_mmap.go b/src/cmd/oldlink/internal/ld/outbuf_mmap.go
deleted file mode 100644
index 4075141..0000000
--- a/src/cmd/oldlink/internal/ld/outbuf_mmap.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2019 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 openbsd
-
-package ld
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-func (out *OutBuf) Mmap(filesize uint64) error {
-	err := out.f.Truncate(int64(filesize))
-	if err != nil {
-		Exitf("resize output file failed: %v", err)
-	}
-	out.buf, err = syscall.Mmap(int(out.f.Fd()), 0, int(filesize), syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED|syscall.MAP_FILE)
-	return err
-}
-
-func (out *OutBuf) Munmap() {
-	err := out.Msync()
-	if err != nil {
-		Exitf("msync output file failed: %v", err)
-	}
-	syscall.Munmap(out.buf)
-	out.buf = nil
-	_, err = out.f.Seek(out.off, 0)
-	if err != nil {
-		Exitf("seek output file failed: %v", err)
-	}
-}
-
-func (out *OutBuf) Msync() error {
-	// TODO: netbsd supports mmap and msync, but the syscall package doesn't define MSYNC.
-	// It is excluded from the build tag for now.
-	_, _, errno := syscall.Syscall(syscall.SYS_MSYNC, uintptr(unsafe.Pointer(&out.buf[0])), uintptr(len(out.buf)), syscall.MS_SYNC)
-	if errno != 0 {
-		return errno
-	}
-	return nil
-}
diff --git a/src/cmd/oldlink/internal/ld/outbuf_nommap.go b/src/cmd/oldlink/internal/ld/outbuf_nommap.go
deleted file mode 100644
index fba8cd8..0000000
--- a/src/cmd/oldlink/internal/ld/outbuf_nommap.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2019 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,!openbsd,!windows
-
-package ld
-
-import "errors"
-
-var errNotSupported = errors.New("mmap not supported")
-
-func (out *OutBuf) Mmap(filesize uint64) error { return errNotSupported }
-func (out *OutBuf) Munmap()                    { panic("unreachable") }
-func (out *OutBuf) Msync() error               { panic("unreachable") }
diff --git a/src/cmd/oldlink/internal/ld/outbuf_windows.go b/src/cmd/oldlink/internal/ld/outbuf_windows.go
deleted file mode 100644
index 1cb05c3..0000000
--- a/src/cmd/oldlink/internal/ld/outbuf_windows.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2019 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 ld
-
-import (
-	"reflect"
-	"syscall"
-	"unsafe"
-)
-
-func (out *OutBuf) Mmap(filesize uint64) error {
-	err := out.f.Truncate(int64(filesize))
-	if err != nil {
-		Exitf("resize output file failed: %v", err)
-	}
-
-	low, high := uint32(filesize), uint32(filesize>>32)
-	fmap, err := syscall.CreateFileMapping(syscall.Handle(out.f.Fd()), nil, syscall.PAGE_READONLY, high, low, nil)
-	if err != nil {
-		return err
-	}
-	defer syscall.CloseHandle(fmap)
-
-	ptr, err := syscall.MapViewOfFile(fmap, syscall.FILE_MAP_READ|syscall.FILE_MAP_WRITE, 0, 0, uintptr(filesize))
-	if err != nil {
-		return err
-	}
-	*(*reflect.SliceHeader)(unsafe.Pointer(&out.buf)) = reflect.SliceHeader{Data: ptr, Len: int(filesize), Cap: int(filesize)}
-	return nil
-}
-
-func (out *OutBuf) Munmap() {
-	if out.buf == nil {
-		return
-	}
-	err := syscall.UnmapViewOfFile(uintptr(unsafe.Pointer(&out.buf[0])))
-	if err != nil {
-		Exitf("UnmapViewOfFile failed: %v", err)
-	}
-}
-
-func (out *OutBuf) Msync() error {
-	if out.buf == nil {
-		return nil
-	}
-	return syscall.FlushViewOfFile(uintptr(unsafe.Pointer(&out.buf[0])), 0)
-}
diff --git a/src/cmd/oldlink/internal/ld/pcln.go b/src/cmd/oldlink/internal/ld/pcln.go
deleted file mode 100644
index 7d53ab8..0000000
--- a/src/cmd/oldlink/internal/ld/pcln.go
+++ /dev/null
@@ -1,530 +0,0 @@
-// 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.
-
-package ld
-
-import (
-	"cmd/internal/obj"
-	"cmd/internal/objabi"
-	"cmd/internal/src"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/sym"
-	"encoding/binary"
-	"fmt"
-	"log"
-	"os"
-	"path/filepath"
-	"strings"
-)
-
-func ftabaddstring(ftab *sym.Symbol, s string) int32 {
-	start := len(ftab.P)
-	ftab.Grow(int64(start + len(s) + 1)) // make room for s plus trailing NUL
-	copy(ftab.P[start:], s)
-	return int32(start)
-}
-
-// numberfile assigns a file number to the file if it hasn't been assigned already.
-func numberfile(ctxt *Link, file *sym.Symbol) {
-	if file.Type != sym.SFILEPATH {
-		ctxt.Filesyms = append(ctxt.Filesyms, file)
-		file.Value = int64(len(ctxt.Filesyms))
-		file.Type = sym.SFILEPATH
-		path := file.Name[len(src.FileSymPrefix):]
-		file.Name = expandGoroot(path)
-	}
-}
-
-func renumberfiles(ctxt *Link, files []*sym.Symbol, d *sym.Pcdata) {
-	// Give files numbers.
-	for _, f := range files {
-		numberfile(ctxt, f)
-	}
-
-	buf := make([]byte, binary.MaxVarintLen32)
-	newval := int32(-1)
-	var out sym.Pcdata
-	it := obj.NewPCIter(uint32(ctxt.Arch.MinLC))
-	for it.Init(d.P); !it.Done; it.Next() {
-		// value delta
-		oldval := it.Value
-
-		var val int32
-		if oldval == -1 {
-			val = -1
-		} else {
-			if oldval < 0 || oldval >= int32(len(files)) {
-				log.Fatalf("bad pcdata %d", oldval)
-			}
-			val = int32(files[oldval].Value)
-		}
-
-		dv := val - newval
-		newval = val
-
-		// value
-		n := binary.PutVarint(buf, int64(dv))
-		out.P = append(out.P, buf[:n]...)
-
-		// pc delta
-		pc := (it.NextPC - it.PC) / it.PCScale
-		n = binary.PutUvarint(buf, uint64(pc))
-		out.P = append(out.P, buf[:n]...)
-	}
-
-	// terminating value delta
-	// we want to write varint-encoded 0, which is just 0
-	out.P = append(out.P, 0)
-
-	*d = out
-}
-
-// onlycsymbol reports whether this is a symbol that is referenced by C code.
-func onlycsymbol(s *sym.Symbol) bool {
-	switch s.Name {
-	case "_cgo_topofstack", "__cgo_topofstack", "_cgo_panic", "crosscall2":
-		return true
-	}
-	if strings.HasPrefix(s.Name, "_cgoexp_") {
-		return true
-	}
-	return false
-}
-
-func emitPcln(ctxt *Link, s *sym.Symbol) bool {
-	if s == nil {
-		return true
-	}
-	if ctxt.BuildMode == BuildModePlugin && ctxt.HeadType == objabi.Hdarwin && onlycsymbol(s) {
-		return false
-	}
-	// We want to generate func table entries only for the "lowest level" symbols,
-	// not containers of subsymbols.
-	return !s.Attr.Container()
-}
-
-// pclntab initializes the pclntab symbol with
-// runtime function and file name information.
-
-var pclntabZpcln sym.FuncInfo
-
-// These variables are used to initialize runtime.firstmoduledata, see symtab.go:symtab.
-var pclntabNfunc int32
-var pclntabFiletabOffset int32
-var pclntabPclntabOffset int32
-var pclntabFirstFunc *sym.Symbol
-var pclntabLastFunc *sym.Symbol
-
-func (ctxt *Link) pclntab() {
-	funcdataBytes := int64(0)
-	ftab := ctxt.Syms.Lookup("runtime.pclntab", 0)
-	ftab.Type = sym.SPCLNTAB
-	ftab.Attr |= sym.AttrReachable
-
-	// See golang.org/s/go12symtab for the format. Briefly:
-	//	8-byte header
-	//	nfunc [thearch.ptrsize bytes]
-	//	function table, alternating PC and offset to func struct [each entry thearch.ptrsize bytes]
-	//	end PC [thearch.ptrsize bytes]
-	//	offset to file table [4 bytes]
-
-	// Find container symbols and mark them as such.
-	for _, s := range ctxt.Textp {
-		if s.Outer != nil {
-			s.Outer.Attr |= sym.AttrContainer
-		}
-	}
-
-	// Gather some basic stats and info.
-	var nfunc int32
-	prevSect := ctxt.Textp[0].Sect
-	for _, s := range ctxt.Textp {
-		if !emitPcln(ctxt, s) {
-			continue
-		}
-		nfunc++
-		if pclntabFirstFunc == nil {
-			pclntabFirstFunc = s
-		}
-		if s.Sect != prevSect {
-			// With multiple text sections, the external linker may insert functions
-			// between the sections, which are not known by Go. This leaves holes in
-			// the PC range covered by the func table. We need to generate an entry
-			// to mark the hole.
-			nfunc++
-			prevSect = s.Sect
-		}
-	}
-
-	pclntabNfunc = nfunc
-	ftab.Grow(8 + int64(ctxt.Arch.PtrSize) + int64(nfunc)*2*int64(ctxt.Arch.PtrSize) + int64(ctxt.Arch.PtrSize) + 4)
-	ftab.SetUint32(ctxt.Arch, 0, 0xfffffffb)
-	ftab.SetUint8(ctxt.Arch, 6, uint8(ctxt.Arch.MinLC))
-	ftab.SetUint8(ctxt.Arch, 7, uint8(ctxt.Arch.PtrSize))
-	ftab.SetUint(ctxt.Arch, 8, uint64(nfunc))
-	pclntabPclntabOffset = int32(8 + ctxt.Arch.PtrSize)
-
-	funcnameoff := make(map[string]int32)
-	nameToOffset := func(name string) int32 {
-		nameoff, ok := funcnameoff[name]
-		if !ok {
-			nameoff = ftabaddstring(ftab, name)
-			funcnameoff[name] = nameoff
-		}
-		return nameoff
-	}
-
-	pctaboff := make(map[string]uint32)
-	writepctab := func(off int32, p []byte) int32 {
-		start, ok := pctaboff[string(p)]
-		if !ok {
-			if len(p) > 0 {
-				start = uint32(len(ftab.P))
-				ftab.AddBytes(p)
-			}
-			pctaboff[string(p)] = start
-		}
-		newoff := int32(ftab.SetUint32(ctxt.Arch, int64(off), start))
-		return newoff
-	}
-
-	nfunc = 0 // repurpose nfunc as a running index
-	prevFunc := ctxt.Textp[0]
-	for _, s := range ctxt.Textp {
-		if !emitPcln(ctxt, s) {
-			continue
-		}
-
-		if s.Sect != prevFunc.Sect {
-			// With multiple text sections, there may be a hole here in the address
-			// space (see the comment above). We use an invalid funcoff value to
-			// mark the hole.
-			// See also runtime/symtab.go:findfunc
-			ftab.SetAddrPlus(ctxt.Arch, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize), prevFunc, prevFunc.Size)
-			ftab.SetUint(ctxt.Arch, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize), ^uint64(0))
-			nfunc++
-		}
-		prevFunc = s
-
-		pcln := s.FuncInfo
-		if pcln == nil {
-			pcln = &pclntabZpcln
-		}
-
-		if len(pcln.InlTree) > 0 {
-			if len(pcln.Pcdata) <= objabi.PCDATA_InlTreeIndex {
-				// Create inlining pcdata table.
-				pcdata := make([]sym.Pcdata, objabi.PCDATA_InlTreeIndex+1)
-				copy(pcdata, pcln.Pcdata)
-				pcln.Pcdata = pcdata
-			}
-
-			if len(pcln.Funcdataoff) <= objabi.FUNCDATA_InlTree {
-				// Create inline tree funcdata.
-				funcdata := make([]*sym.Symbol, objabi.FUNCDATA_InlTree+1)
-				funcdataoff := make([]int64, objabi.FUNCDATA_InlTree+1)
-				copy(funcdata, pcln.Funcdata)
-				copy(funcdataoff, pcln.Funcdataoff)
-				pcln.Funcdata = funcdata
-				pcln.Funcdataoff = funcdataoff
-			}
-		}
-
-		funcstart := int32(len(ftab.P))
-		funcstart += int32(-len(ftab.P)) & (int32(ctxt.Arch.PtrSize) - 1) // align to ptrsize
-
-		ftab.SetAddr(ctxt.Arch, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize), s)
-		ftab.SetUint(ctxt.Arch, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize), uint64(funcstart))
-
-		// Write runtime._func. Keep in sync with ../../../../runtime/runtime2.go:/_func
-		// and package debug/gosym.
-
-		// fixed size of struct, checked below
-		off := funcstart
-
-		end := funcstart + int32(ctxt.Arch.PtrSize) + 3*4 + 5*4 + int32(len(pcln.Pcdata))*4 + int32(len(pcln.Funcdata))*int32(ctxt.Arch.PtrSize)
-		if len(pcln.Funcdata) > 0 && (end&int32(ctxt.Arch.PtrSize-1) != 0) {
-			end += 4
-		}
-		ftab.Grow(int64(end))
-
-		// entry uintptr
-		off = int32(ftab.SetAddr(ctxt.Arch, int64(off), s))
-
-		// name int32
-		nameoff := nameToOffset(s.Name)
-		off = int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(nameoff)))
-
-		// args int32
-		// TODO: Move into funcinfo.
-		args := uint32(0)
-		if s.FuncInfo != nil {
-			args = uint32(s.FuncInfo.Args)
-		}
-		off = int32(ftab.SetUint32(ctxt.Arch, int64(off), args))
-
-		// deferreturn
-		deferreturn := uint32(0)
-		lastWasmAddr := uint32(0)
-		for _, r := range s.R {
-			if ctxt.Arch.Family == sys.Wasm && r.Type == objabi.R_ADDR {
-				// Wasm does not have a live variable set at the deferreturn
-				// call itself. Instead it has one identified by the
-				// resumption point immediately preceding the deferreturn.
-				// The wasm code has a R_ADDR relocation which is used to
-				// set the resumption point to PC_B.
-				lastWasmAddr = uint32(r.Add)
-			}
-			if r.Type.IsDirectCall() && r.Sym != nil && r.Sym.Name == "runtime.deferreturn" {
-				if ctxt.Arch.Family == sys.Wasm {
-					deferreturn = lastWasmAddr - 1
-				} else {
-					// Note: the relocation target is in the call instruction, but
-					// is not necessarily the whole instruction (for instance, on
-					// x86 the relocation applies to bytes [1:5] of the 5 byte call
-					// instruction).
-					deferreturn = uint32(r.Off)
-					switch ctxt.Arch.Family {
-					case sys.AMD64, sys.I386:
-						deferreturn--
-					case sys.PPC64, sys.ARM, sys.ARM64, sys.MIPS, sys.MIPS64:
-						// no change
-					case sys.RISCV64:
-						// TODO(jsing): The JALR instruction is marked with
-						// R_CALLRISCV, whereas the actual reloc is currently
-						// one instruction earlier starting with the AUIPC.
-						deferreturn -= 4
-					case sys.S390X:
-						deferreturn -= 2
-					default:
-						panic(fmt.Sprint("Unhandled architecture:", ctxt.Arch.Family))
-					}
-				}
-				break // only need one
-			}
-		}
-		off = int32(ftab.SetUint32(ctxt.Arch, int64(off), deferreturn))
-
-		if pcln != &pclntabZpcln {
-			renumberfiles(ctxt, pcln.File, &pcln.Pcfile)
-			if false {
-				// Sanity check the new numbering
-				it := obj.NewPCIter(uint32(ctxt.Arch.MinLC))
-				for it.Init(pcln.Pcfile.P); !it.Done; it.Next() {
-					if it.Value < 1 || it.Value > int32(len(ctxt.Filesyms)) {
-						Errorf(s, "bad file number in pcfile: %d not in range [1, %d]\n", it.Value, len(ctxt.Filesyms))
-						errorexit()
-					}
-				}
-			}
-		}
-
-		if len(pcln.InlTree) > 0 {
-			inlTreeSym := ctxt.Syms.Lookup("inltree."+s.Name, 0)
-			inlTreeSym.Type = sym.SRODATA
-			inlTreeSym.Attr |= sym.AttrReachable | sym.AttrDuplicateOK
-
-			for i, call := range pcln.InlTree {
-				// Usually, call.File is already numbered since the file
-				// shows up in the Pcfile table. However, two inlined calls
-				// might overlap exactly so that only the innermost file
-				// appears in the Pcfile table. In that case, this assigns
-				// the outer file a number.
-				numberfile(ctxt, call.File)
-				nameoff := nameToOffset(call.Func)
-
-				inlTreeSym.SetUint16(ctxt.Arch, int64(i*20+0), uint16(call.Parent))
-				inlTreeSym.SetUint8(ctxt.Arch, int64(i*20+2), uint8(objabi.GetFuncID(call.Func, "")))
-				// byte 3 is unused
-				inlTreeSym.SetUint32(ctxt.Arch, int64(i*20+4), uint32(call.File.Value))
-				inlTreeSym.SetUint32(ctxt.Arch, int64(i*20+8), uint32(call.Line))
-				inlTreeSym.SetUint32(ctxt.Arch, int64(i*20+12), uint32(nameoff))
-				inlTreeSym.SetUint32(ctxt.Arch, int64(i*20+16), uint32(call.ParentPC))
-			}
-
-			pcln.Funcdata[objabi.FUNCDATA_InlTree] = inlTreeSym
-			pcln.Pcdata[objabi.PCDATA_InlTreeIndex] = pcln.Pcinline
-		}
-
-		// pcdata
-		off = writepctab(off, pcln.Pcsp.P)
-		off = writepctab(off, pcln.Pcfile.P)
-		off = writepctab(off, pcln.Pcline.P)
-		off = int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(len(pcln.Pcdata))))
-
-		// funcID uint8
-		var file string
-		if s.FuncInfo != nil && len(s.FuncInfo.File) > 0 {
-			file = s.FuncInfo.File[0].Name
-		}
-		funcID := objabi.GetFuncID(s.Name, file)
-
-		off = int32(ftab.SetUint8(ctxt.Arch, int64(off), uint8(funcID)))
-
-		// unused
-		off += 2
-
-		// nfuncdata must be the final entry.
-		off = int32(ftab.SetUint8(ctxt.Arch, int64(off), uint8(len(pcln.Funcdata))))
-		for i := range pcln.Pcdata {
-			off = writepctab(off, pcln.Pcdata[i].P)
-		}
-
-		// funcdata, must be pointer-aligned and we're only int32-aligned.
-		// Missing funcdata will be 0 (nil pointer).
-		if len(pcln.Funcdata) > 0 {
-			if off&int32(ctxt.Arch.PtrSize-1) != 0 {
-				off += 4
-			}
-			for i := range pcln.Funcdata {
-				dataoff := int64(off) + int64(ctxt.Arch.PtrSize)*int64(i)
-				if pcln.Funcdata[i] == nil {
-					ftab.SetUint(ctxt.Arch, dataoff, uint64(pcln.Funcdataoff[i]))
-					continue
-				}
-				// TODO: Dedup.
-				funcdataBytes += pcln.Funcdata[i].Size
-				ftab.SetAddrPlus(ctxt.Arch, dataoff, pcln.Funcdata[i], pcln.Funcdataoff[i])
-			}
-			off += int32(len(pcln.Funcdata)) * int32(ctxt.Arch.PtrSize)
-		}
-
-		if off != end {
-			Errorf(s, "bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d ptrsize=%d)", funcstart, off, end, len(pcln.Pcdata), len(pcln.Funcdata), ctxt.Arch.PtrSize)
-			errorexit()
-		}
-
-		nfunc++
-	}
-
-	last := ctxt.Textp[len(ctxt.Textp)-1]
-	pclntabLastFunc = last
-	// Final entry of table is just end pc.
-	ftab.SetAddrPlus(ctxt.Arch, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize), last, last.Size)
-
-	// Start file table.
-	start := int32(len(ftab.P))
-
-	start += int32(-len(ftab.P)) & (int32(ctxt.Arch.PtrSize) - 1)
-	pclntabFiletabOffset = start
-	ftab.SetUint32(ctxt.Arch, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize), uint32(start))
-
-	ftab.Grow(int64(start) + (int64(len(ctxt.Filesyms))+1)*4)
-	ftab.SetUint32(ctxt.Arch, int64(start), uint32(len(ctxt.Filesyms)+1))
-	for i := len(ctxt.Filesyms) - 1; i >= 0; i-- {
-		s := ctxt.Filesyms[i]
-		ftab.SetUint32(ctxt.Arch, int64(start)+s.Value*4, uint32(ftabaddstring(ftab, s.Name)))
-	}
-
-	ftab.Size = int64(len(ftab.P))
-
-	if ctxt.Debugvlog != 0 {
-		ctxt.Logf("pclntab=%d bytes, funcdata total %d bytes\n", ftab.Size, funcdataBytes)
-	}
-}
-
-func gorootFinal() string {
-	root := objabi.GOROOT
-	if final := os.Getenv("GOROOT_FINAL"); final != "" {
-		root = final
-	}
-	return root
-}
-
-func expandGoroot(s string) string {
-	const n = len("$GOROOT")
-	if len(s) >= n+1 && s[:n] == "$GOROOT" && (s[n] == '/' || s[n] == '\\') {
-		return filepath.ToSlash(filepath.Join(gorootFinal(), s[n:]))
-	}
-	return s
-}
-
-const (
-	BUCKETSIZE    = 256 * MINFUNC
-	SUBBUCKETS    = 16
-	SUBBUCKETSIZE = BUCKETSIZE / SUBBUCKETS
-	NOIDX         = 0x7fffffff
-)
-
-// findfunctab generates a lookup table to quickly find the containing
-// function for a pc. See src/runtime/symtab.go:findfunc for details.
-func (ctxt *Link) findfunctab() {
-	t := ctxt.Syms.Lookup("runtime.findfunctab", 0)
-	t.Type = sym.SRODATA
-	t.Attr |= sym.AttrReachable
-	t.Attr |= sym.AttrLocal
-
-	// find min and max address
-	min := ctxt.Textp[0].Value
-	lastp := ctxt.Textp[len(ctxt.Textp)-1]
-	max := lastp.Value + lastp.Size
-
-	// for each subbucket, compute the minimum of all symbol indexes
-	// that map to that subbucket.
-	n := int32((max - min + SUBBUCKETSIZE - 1) / SUBBUCKETSIZE)
-
-	indexes := make([]int32, n)
-	for i := int32(0); i < n; i++ {
-		indexes[i] = NOIDX
-	}
-	idx := int32(0)
-	for i, s := range ctxt.Textp {
-		if !emitPcln(ctxt, s) {
-			continue
-		}
-		p := s.Value
-		var e *sym.Symbol
-		i++
-		if i < len(ctxt.Textp) {
-			e = ctxt.Textp[i]
-		}
-		for !emitPcln(ctxt, e) && i < len(ctxt.Textp) {
-			e = ctxt.Textp[i]
-			i++
-		}
-		q := max
-		if e != nil {
-			q = e.Value
-		}
-
-		//print("%d: [%lld %lld] %s\n", idx, p, q, s->name);
-		for ; p < q; p += SUBBUCKETSIZE {
-			i = int((p - min) / SUBBUCKETSIZE)
-			if indexes[i] > idx {
-				indexes[i] = idx
-			}
-		}
-
-		i = int((q - 1 - min) / SUBBUCKETSIZE)
-		if indexes[i] > idx {
-			indexes[i] = idx
-		}
-		idx++
-	}
-
-	// allocate table
-	nbuckets := int32((max - min + BUCKETSIZE - 1) / BUCKETSIZE)
-
-	t.Grow(4*int64(nbuckets) + int64(n))
-
-	// fill in table
-	for i := int32(0); i < nbuckets; i++ {
-		base := indexes[i*SUBBUCKETS]
-		if base == NOIDX {
-			Errorf(nil, "hole in findfunctab")
-		}
-		t.SetUint32(ctxt.Arch, int64(i)*(4+SUBBUCKETS), uint32(base))
-		for j := int32(0); j < SUBBUCKETS && i*SUBBUCKETS+j < n; j++ {
-			idx = indexes[i*SUBBUCKETS+j]
-			if idx == NOIDX {
-				Errorf(nil, "hole in findfunctab")
-			}
-			if idx-base >= 256 {
-				Errorf(nil, "too many functions in a findfunc bucket! %d/%d %d %d", i, nbuckets, j, idx-base)
-			}
-
-			t.SetUint8(ctxt.Arch, int64(i)*(4+SUBBUCKETS)+4+int64(j), uint8(idx-base))
-		}
-	}
-}
diff --git a/src/cmd/oldlink/internal/ld/pe.go b/src/cmd/oldlink/internal/ld/pe.go
deleted file mode 100644
index b40557f..0000000
--- a/src/cmd/oldlink/internal/ld/pe.go
+++ /dev/null
@@ -1,1562 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// PE (Portable Executable) file writing
-// https://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
-
-package ld
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/sym"
-	"debug/pe"
-	"encoding/binary"
-	"fmt"
-	"sort"
-	"strconv"
-	"strings"
-)
-
-type IMAGE_IMPORT_DESCRIPTOR struct {
-	OriginalFirstThunk uint32
-	TimeDateStamp      uint32
-	ForwarderChain     uint32
-	Name               uint32
-	FirstThunk         uint32
-}
-
-type IMAGE_EXPORT_DIRECTORY struct {
-	Characteristics       uint32
-	TimeDateStamp         uint32
-	MajorVersion          uint16
-	MinorVersion          uint16
-	Name                  uint32
-	Base                  uint32
-	NumberOfFunctions     uint32
-	NumberOfNames         uint32
-	AddressOfFunctions    uint32
-	AddressOfNames        uint32
-	AddressOfNameOrdinals uint32
-}
-
-const (
-	PEBASE = 0x00400000
-)
-
-var (
-	// SectionAlignment must be greater than or equal to FileAlignment.
-	// The default is the page size for the architecture.
-	PESECTALIGN int64 = 0x1000
-
-	// FileAlignment should be a power of 2 between 512 and 64 K, inclusive.
-	// The default is 512. If the SectionAlignment is less than
-	// the architecture's page size, then FileAlignment must match SectionAlignment.
-	PEFILEALIGN int64 = 2 << 8
-)
-
-const (
-	IMAGE_SCN_CNT_CODE               = 0x00000020
-	IMAGE_SCN_CNT_INITIALIZED_DATA   = 0x00000040
-	IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080
-	IMAGE_SCN_MEM_EXECUTE            = 0x20000000
-	IMAGE_SCN_MEM_READ               = 0x40000000
-	IMAGE_SCN_MEM_WRITE              = 0x80000000
-	IMAGE_SCN_MEM_DISCARDABLE        = 0x2000000
-	IMAGE_SCN_LNK_NRELOC_OVFL        = 0x1000000
-	IMAGE_SCN_ALIGN_32BYTES          = 0x600000
-)
-
-// TODO(crawshaw): add these constants to debug/pe.
-const (
-	// TODO: the Microsoft doco says IMAGE_SYM_DTYPE_ARRAY is 3 and IMAGE_SYM_DTYPE_FUNCTION is 2
-	IMAGE_SYM_TYPE_NULL      = 0
-	IMAGE_SYM_TYPE_STRUCT    = 8
-	IMAGE_SYM_DTYPE_FUNCTION = 0x20
-	IMAGE_SYM_DTYPE_ARRAY    = 0x30
-	IMAGE_SYM_CLASS_EXTERNAL = 2
-	IMAGE_SYM_CLASS_STATIC   = 3
-
-	IMAGE_REL_I386_DIR32  = 0x0006
-	IMAGE_REL_I386_SECREL = 0x000B
-	IMAGE_REL_I386_REL32  = 0x0014
-
-	IMAGE_REL_AMD64_ADDR64 = 0x0001
-	IMAGE_REL_AMD64_ADDR32 = 0x0002
-	IMAGE_REL_AMD64_REL32  = 0x0004
-	IMAGE_REL_AMD64_SECREL = 0x000B
-
-	IMAGE_REL_ARM_ABSOLUTE = 0x0000
-	IMAGE_REL_ARM_ADDR32   = 0x0001
-	IMAGE_REL_ARM_ADDR32NB = 0x0002
-	IMAGE_REL_ARM_BRANCH24 = 0x0003
-	IMAGE_REL_ARM_BRANCH11 = 0x0004
-	IMAGE_REL_ARM_SECREL   = 0x000F
-
-	IMAGE_REL_BASED_HIGHLOW = 3
-	IMAGE_REL_BASED_DIR64   = 10
-)
-
-const (
-	PeMinimumTargetMajorVersion = 6
-	PeMinimumTargetMinorVersion = 1
-)
-
-// DOS stub that prints out
-// "This program cannot be run in DOS mode."
-var dosstub = []uint8{
-	0x4d,
-	0x5a,
-	0x90,
-	0x00,
-	0x03,
-	0x00,
-	0x04,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0xff,
-	0xff,
-	0x00,
-	0x00,
-	0x8b,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x40,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x80,
-	0x00,
-	0x00,
-	0x00,
-	0x0e,
-	0x1f,
-	0xba,
-	0x0e,
-	0x00,
-	0xb4,
-	0x09,
-	0xcd,
-	0x21,
-	0xb8,
-	0x01,
-	0x4c,
-	0xcd,
-	0x21,
-	0x54,
-	0x68,
-	0x69,
-	0x73,
-	0x20,
-	0x70,
-	0x72,
-	0x6f,
-	0x67,
-	0x72,
-	0x61,
-	0x6d,
-	0x20,
-	0x63,
-	0x61,
-	0x6e,
-	0x6e,
-	0x6f,
-	0x74,
-	0x20,
-	0x62,
-	0x65,
-	0x20,
-	0x72,
-	0x75,
-	0x6e,
-	0x20,
-	0x69,
-	0x6e,
-	0x20,
-	0x44,
-	0x4f,
-	0x53,
-	0x20,
-	0x6d,
-	0x6f,
-	0x64,
-	0x65,
-	0x2e,
-	0x0d,
-	0x0d,
-	0x0a,
-	0x24,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-	0x00,
-}
-
-type Imp struct {
-	s       *sym.Symbol
-	off     uint64
-	next    *Imp
-	argsize int
-}
-
-type Dll struct {
-	name     string
-	nameoff  uint64
-	thunkoff uint64
-	ms       *Imp
-	next     *Dll
-}
-
-var (
-	rsrcsym     *sym.Symbol
-	PESECTHEADR int32
-	PEFILEHEADR int32
-	pe64        int
-	dr          *Dll
-	dexport     [1024]*sym.Symbol
-	nexport     int
-)
-
-// peStringTable is a COFF string table.
-type peStringTable struct {
-	strings    []string
-	stringsLen int
-}
-
-// size returns size of string table t.
-func (t *peStringTable) size() int {
-	// string table starts with 4-byte length at the beginning
-	return t.stringsLen + 4
-}
-
-// add adds string str to string table t.
-func (t *peStringTable) add(str string) int {
-	off := t.size()
-	t.strings = append(t.strings, str)
-	t.stringsLen += len(str) + 1 // each string will have 0 appended to it
-	return off
-}
-
-// write writes string table t into the output file.
-func (t *peStringTable) write(out *OutBuf) {
-	out.Write32(uint32(t.size()))
-	for _, s := range t.strings {
-		out.WriteString(s)
-		out.Write8(0)
-	}
-}
-
-// peSection represents section from COFF section table.
-type peSection struct {
-	name                 string
-	shortName            string
-	index                int // one-based index into the Section Table
-	virtualSize          uint32
-	virtualAddress       uint32
-	sizeOfRawData        uint32
-	pointerToRawData     uint32
-	pointerToRelocations uint32
-	numberOfRelocations  uint16
-	characteristics      uint32
-}
-
-// checkOffset verifies COFF section sect offset in the file.
-func (sect *peSection) checkOffset(off int64) {
-	if off != int64(sect.pointerToRawData) {
-		Errorf(nil, "%s.PointerToRawData = %#x, want %#x", sect.name, uint64(int64(sect.pointerToRawData)), uint64(off))
-		errorexit()
-	}
-}
-
-// checkSegment verifies COFF section sect matches address
-// and file offset provided in segment seg.
-func (sect *peSection) checkSegment(seg *sym.Segment) {
-	if seg.Vaddr-PEBASE != uint64(sect.virtualAddress) {
-		Errorf(nil, "%s.VirtualAddress = %#x, want %#x", sect.name, uint64(int64(sect.virtualAddress)), uint64(int64(seg.Vaddr-PEBASE)))
-		errorexit()
-	}
-	if seg.Fileoff != uint64(sect.pointerToRawData) {
-		Errorf(nil, "%s.PointerToRawData = %#x, want %#x", sect.name, uint64(int64(sect.pointerToRawData)), uint64(int64(seg.Fileoff)))
-		errorexit()
-	}
-}
-
-// pad adds zeros to the section sect. It writes as many bytes
-// as necessary to make section sect.SizeOfRawData bytes long.
-// It assumes that n bytes are already written to the file.
-func (sect *peSection) pad(out *OutBuf, n uint32) {
-	out.WriteStringN("", int(sect.sizeOfRawData-n))
-}
-
-// write writes COFF section sect into the output file.
-func (sect *peSection) write(out *OutBuf, linkmode LinkMode) error {
-	h := pe.SectionHeader32{
-		VirtualSize:          sect.virtualSize,
-		SizeOfRawData:        sect.sizeOfRawData,
-		PointerToRawData:     sect.pointerToRawData,
-		PointerToRelocations: sect.pointerToRelocations,
-		NumberOfRelocations:  sect.numberOfRelocations,
-		Characteristics:      sect.characteristics,
-	}
-	if linkmode != LinkExternal {
-		h.VirtualAddress = sect.virtualAddress
-	}
-	copy(h.Name[:], sect.shortName)
-	return binary.Write(out, binary.LittleEndian, h)
-}
-
-// emitRelocations emits the relocation entries for the sect.
-// The actual relocations are emitted by relocfn.
-// This updates the corresponding PE section table entry
-// with the relocation offset and count.
-func (sect *peSection) emitRelocations(out *OutBuf, relocfn func() int) {
-	sect.pointerToRelocations = uint32(out.Offset())
-	// first entry: extended relocs
-	out.Write32(0) // placeholder for number of relocation + 1
-	out.Write32(0)
-	out.Write16(0)
-
-	n := relocfn() + 1
-
-	cpos := out.Offset()
-	out.SeekSet(int64(sect.pointerToRelocations))
-	out.Write32(uint32(n))
-	out.SeekSet(cpos)
-	if n > 0x10000 {
-		n = 0x10000
-		sect.characteristics |= IMAGE_SCN_LNK_NRELOC_OVFL
-	} else {
-		sect.pointerToRelocations += 10 // skip the extend reloc entry
-	}
-	sect.numberOfRelocations = uint16(n - 1)
-}
-
-// peFile is used to build COFF file.
-type peFile struct {
-	sections       []*peSection
-	stringTable    peStringTable
-	textSect       *peSection
-	rdataSect      *peSection
-	dataSect       *peSection
-	bssSect        *peSection
-	ctorsSect      *peSection
-	nextSectOffset uint32
-	nextFileOffset uint32
-	symtabOffset   int64 // offset to the start of symbol table
-	symbolCount    int   // number of symbol table records written
-	dataDirectory  [16]pe.DataDirectory
-}
-
-// addSection adds section to the COFF file f.
-func (f *peFile) addSection(name string, sectsize int, filesize int) *peSection {
-	sect := &peSection{
-		name:             name,
-		shortName:        name,
-		index:            len(f.sections) + 1,
-		virtualSize:      uint32(sectsize),
-		virtualAddress:   f.nextSectOffset,
-		pointerToRawData: f.nextFileOffset,
-	}
-	f.nextSectOffset = uint32(Rnd(int64(f.nextSectOffset)+int64(sectsize), PESECTALIGN))
-	if filesize > 0 {
-		sect.sizeOfRawData = uint32(Rnd(int64(filesize), PEFILEALIGN))
-		f.nextFileOffset += sect.sizeOfRawData
-	}
-	f.sections = append(f.sections, sect)
-	return sect
-}
-
-// addDWARFSection adds DWARF section to the COFF file f.
-// This function is similar to addSection, but DWARF section names are
-// longer than 8 characters, so they need to be stored in the string table.
-func (f *peFile) addDWARFSection(name string, size int) *peSection {
-	if size == 0 {
-		Exitf("DWARF section %q is empty", name)
-	}
-	// DWARF section names are longer than 8 characters.
-	// PE format requires such names to be stored in string table,
-	// and section names replaced with slash (/) followed by
-	// correspondent string table index.
-	// see http://www.microsoft.com/whdc/system/platform/firmware/PECOFFdwn.mspx
-	// for details
-	off := f.stringTable.add(name)
-	h := f.addSection(name, size, size)
-	h.shortName = fmt.Sprintf("/%d", off)
-	h.characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
-	return h
-}
-
-// addDWARF adds DWARF information to the COFF file f.
-func (f *peFile) addDWARF() {
-	if *FlagS { // disable symbol table
-		return
-	}
-	if *FlagW { // disable dwarf
-		return
-	}
-	for _, sect := range Segdwarf.Sections {
-		h := f.addDWARFSection(sect.Name, int(sect.Length))
-		fileoff := sect.Vaddr - Segdwarf.Vaddr + Segdwarf.Fileoff
-		if uint64(h.pointerToRawData) != fileoff {
-			Exitf("%s.PointerToRawData = %#x, want %#x", sect.Name, h.pointerToRawData, fileoff)
-		}
-	}
-}
-
-// addInitArray adds .ctors COFF section to the file f.
-func (f *peFile) addInitArray(ctxt *Link) *peSection {
-	// The size below was determined by the specification for array relocations,
-	// and by observing what GCC writes here. If the initarray section grows to
-	// contain more than one constructor entry, the size will need to be 8 * constructor_count.
-	// However, the entire Go runtime is initialized from just one function, so it is unlikely
-	// that this will need to grow in the future.
-	var size int
-	switch objabi.GOARCH {
-	default:
-		Exitf("peFile.addInitArray: unsupported GOARCH=%q\n", objabi.GOARCH)
-	case "386":
-		size = 4
-	case "amd64":
-		size = 8
-	case "arm":
-		size = 4
-	}
-	sect := f.addSection(".ctors", size, size)
-	sect.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
-	sect.sizeOfRawData = uint32(size)
-	ctxt.Out.SeekSet(int64(sect.pointerToRawData))
-	sect.checkOffset(ctxt.Out.Offset())
-
-	init_entry := ctxt.Syms.Lookup(*flagEntrySymbol, 0)
-	addr := uint64(init_entry.Value) - init_entry.Sect.Vaddr
-	switch objabi.GOARCH {
-	case "386", "arm":
-		ctxt.Out.Write32(uint32(addr))
-	case "amd64":
-		ctxt.Out.Write64(addr)
-	}
-	return sect
-}
-
-// emitRelocations emits relocation entries for go.o in external linking.
-func (f *peFile) emitRelocations(ctxt *Link) {
-	for ctxt.Out.Offset()&7 != 0 {
-		ctxt.Out.Write8(0)
-	}
-
-	// relocsect relocates symbols from first in section sect, and returns
-	// the total number of relocations emitted.
-	relocsect := func(sect *sym.Section, syms []*sym.Symbol, base uint64) int {
-		// If main section has no bits, nothing to relocate.
-		if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
-			return 0
-		}
-		relocs := 0
-		sect.Reloff = uint64(ctxt.Out.Offset())
-		for i, s := range syms {
-			if !s.Attr.Reachable() {
-				continue
-			}
-			if uint64(s.Value) >= sect.Vaddr {
-				syms = syms[i:]
-				break
-			}
-		}
-		eaddr := int32(sect.Vaddr + sect.Length)
-		for _, sym := range syms {
-			if !sym.Attr.Reachable() {
-				continue
-			}
-			if sym.Value >= int64(eaddr) {
-				break
-			}
-			for ri := range sym.R {
-				r := &sym.R[ri]
-				if r.Done {
-					continue
-				}
-				if r.Xsym == nil {
-					Errorf(sym, "missing xsym in relocation")
-					continue
-				}
-				if r.Xsym.Dynid < 0 {
-					Errorf(sym, "reloc %d to non-coff symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
-				}
-				if !thearch.PEreloc1(ctxt.Arch, ctxt.Out, sym, r, int64(uint64(sym.Value+int64(r.Off))-base)) {
-					Errorf(sym, "unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
-				}
-				relocs++
-			}
-		}
-		sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
-		return relocs
-	}
-
-	sects := []struct {
-		peSect *peSection
-		seg    *sym.Segment
-		syms   []*sym.Symbol
-	}{
-		{f.textSect, &Segtext, ctxt.Textp},
-		{f.rdataSect, &Segrodata, datap},
-		{f.dataSect, &Segdata, datap},
-	}
-	for _, s := range sects {
-		s.peSect.emitRelocations(ctxt.Out, func() int {
-			var n int
-			for _, sect := range s.seg.Sections {
-				n += relocsect(sect, s.syms, s.seg.Vaddr)
-			}
-			return n
-		})
-	}
-
-dwarfLoop:
-	for _, sect := range Segdwarf.Sections {
-		for _, pesect := range f.sections {
-			if sect.Name == pesect.name {
-				pesect.emitRelocations(ctxt.Out, func() int {
-					return relocsect(sect, dwarfp, sect.Vaddr)
-				})
-				continue dwarfLoop
-			}
-		}
-		Errorf(nil, "emitRelocations: could not find %q section", sect.Name)
-	}
-
-	f.ctorsSect.emitRelocations(ctxt.Out, func() int {
-		dottext := ctxt.Syms.Lookup(".text", 0)
-		ctxt.Out.Write32(0)
-		ctxt.Out.Write32(uint32(dottext.Dynid))
-		switch objabi.GOARCH {
-		default:
-			Errorf(dottext, "unknown architecture for PE: %q\n", objabi.GOARCH)
-		case "386":
-			ctxt.Out.Write16(IMAGE_REL_I386_DIR32)
-		case "amd64":
-			ctxt.Out.Write16(IMAGE_REL_AMD64_ADDR64)
-		case "arm":
-			ctxt.Out.Write16(IMAGE_REL_ARM_ADDR32)
-		}
-		return 1
-	})
-}
-
-// writeSymbol appends symbol s to file f symbol table.
-// It also sets s.Dynid to written symbol number.
-func (f *peFile) writeSymbol(out *OutBuf, s *sym.Symbol, value int64, sectidx int, typ uint16, class uint8) {
-	if len(s.Name) > 8 {
-		out.Write32(0)
-		out.Write32(uint32(f.stringTable.add(s.Name)))
-	} else {
-		out.WriteStringN(s.Name, 8)
-	}
-	out.Write32(uint32(value))
-	out.Write16(uint16(sectidx))
-	out.Write16(typ)
-	out.Write8(class)
-	out.Write8(0) // no aux entries
-
-	s.Dynid = int32(f.symbolCount)
-
-	f.symbolCount++
-}
-
-// mapToPESection searches peFile f for s symbol's location.
-// It returns PE section index, and offset within that section.
-func (f *peFile) mapToPESection(s *sym.Symbol, linkmode LinkMode) (pesectidx int, offset int64, err error) {
-	if s.Sect == nil {
-		return 0, 0, fmt.Errorf("could not map %s symbol with no section", s.Name)
-	}
-	if s.Sect.Seg == &Segtext {
-		return f.textSect.index, int64(uint64(s.Value) - Segtext.Vaddr), nil
-	}
-	if s.Sect.Seg == &Segrodata {
-		return f.rdataSect.index, int64(uint64(s.Value) - Segrodata.Vaddr), nil
-	}
-	if s.Sect.Seg != &Segdata {
-		return 0, 0, fmt.Errorf("could not map %s symbol with non .text or .rdata or .data section", s.Name)
-	}
-	v := uint64(s.Value) - Segdata.Vaddr
-	if linkmode != LinkExternal {
-		return f.dataSect.index, int64(v), nil
-	}
-	if s.Type == sym.SDATA {
-		return f.dataSect.index, int64(v), nil
-	}
-	// Note: although address of runtime.edata (type sym.SDATA) is at the start of .bss section
-	// it still belongs to the .data section, not the .bss section.
-	if v < Segdata.Filelen {
-		return f.dataSect.index, int64(v), nil
-	}
-	return f.bssSect.index, int64(v - Segdata.Filelen), nil
-}
-
-// writeSymbols writes all COFF symbol table records.
-func (f *peFile) writeSymbols(ctxt *Link) {
-
-	put := func(ctxt *Link, s *sym.Symbol, name string, type_ SymbolType, addr int64, gotype *sym.Symbol) {
-		if s == nil {
-			return
-		}
-		if s.Sect == nil && type_ != UndefinedSym {
-			return
-		}
-		switch type_ {
-		default:
-			return
-		case DataSym, BSSSym, TextSym, UndefinedSym:
-		}
-
-		// Only windows/386 requires underscore prefix on external symbols.
-		if ctxt.Arch.Family == sys.I386 &&
-			ctxt.LinkMode == LinkExternal &&
-			(s.Type == sym.SHOSTOBJ || s.Type == sym.SUNDEFEXT || s.Attr.CgoExport()) {
-			s.Name = "_" + s.Name
-		}
-
-		var typ uint16
-		if ctxt.LinkMode == LinkExternal {
-			typ = IMAGE_SYM_TYPE_NULL
-		} else {
-			// TODO: fix IMAGE_SYM_DTYPE_ARRAY value and use following expression, instead of 0x0308
-			typ = IMAGE_SYM_DTYPE_ARRAY<<8 + IMAGE_SYM_TYPE_STRUCT
-			typ = 0x0308 // "array of structs"
-		}
-		sect, value, err := f.mapToPESection(s, ctxt.LinkMode)
-		if err != nil {
-			if type_ == UndefinedSym {
-				typ = IMAGE_SYM_DTYPE_FUNCTION
-			} else {
-				Errorf(s, "addpesym: %v", err)
-			}
-		}
-		class := IMAGE_SYM_CLASS_EXTERNAL
-		if s.IsFileLocal() || s.Attr.VisibilityHidden() || s.Attr.Local() {
-			class = IMAGE_SYM_CLASS_STATIC
-		}
-		f.writeSymbol(ctxt.Out, s, value, sect, typ, uint8(class))
-	}
-
-	if ctxt.LinkMode == LinkExternal {
-		// Include section symbols as external, because
-		// .ctors and .debug_* section relocations refer to it.
-		for _, pesect := range f.sections {
-			sym := ctxt.Syms.Lookup(pesect.name, 0)
-			f.writeSymbol(ctxt.Out, sym, 0, pesect.index, IMAGE_SYM_TYPE_NULL, IMAGE_SYM_CLASS_STATIC)
-		}
-	}
-
-	genasmsym(ctxt, put)
-}
-
-// writeSymbolTableAndStringTable writes out symbol and string tables for peFile f.
-func (f *peFile) writeSymbolTableAndStringTable(ctxt *Link) {
-	f.symtabOffset = ctxt.Out.Offset()
-
-	// write COFF symbol table
-	if !*FlagS || ctxt.LinkMode == LinkExternal {
-		f.writeSymbols(ctxt)
-	}
-
-	// update COFF file header and section table
-	size := f.stringTable.size() + 18*f.symbolCount
-	var h *peSection
-	if ctxt.LinkMode != LinkExternal {
-		// We do not really need .symtab for go.o, and if we have one, ld
-		// will also include it in the exe, and that will confuse windows.
-		h = f.addSection(".symtab", size, size)
-		h.characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
-		h.checkOffset(f.symtabOffset)
-	}
-
-	// write COFF string table
-	f.stringTable.write(ctxt.Out)
-	if ctxt.LinkMode != LinkExternal {
-		h.pad(ctxt.Out, uint32(size))
-	}
-}
-
-// writeFileHeader writes COFF file header for peFile f.
-func (f *peFile) writeFileHeader(ctxt *Link) {
-	var fh pe.FileHeader
-
-	switch ctxt.Arch.Family {
-	default:
-		Exitf("unknown PE architecture: %v", ctxt.Arch.Family)
-	case sys.AMD64:
-		fh.Machine = pe.IMAGE_FILE_MACHINE_AMD64
-	case sys.I386:
-		fh.Machine = pe.IMAGE_FILE_MACHINE_I386
-	case sys.ARM:
-		fh.Machine = pe.IMAGE_FILE_MACHINE_ARMNT
-	}
-
-	fh.NumberOfSections = uint16(len(f.sections))
-
-	// Being able to produce identical output for identical input is
-	// much more beneficial than having build timestamp in the header.
-	fh.TimeDateStamp = 0
-
-	if ctxt.LinkMode == LinkExternal {
-		fh.Characteristics = pe.IMAGE_FILE_LINE_NUMS_STRIPPED
-	} else {
-		fh.Characteristics = pe.IMAGE_FILE_EXECUTABLE_IMAGE | pe.IMAGE_FILE_DEBUG_STRIPPED
-		switch ctxt.Arch.Family {
-		case sys.AMD64, sys.I386:
-			if ctxt.BuildMode != BuildModePIE {
-				fh.Characteristics |= pe.IMAGE_FILE_RELOCS_STRIPPED
-			}
-		}
-	}
-	if pe64 != 0 {
-		var oh64 pe.OptionalHeader64
-		fh.SizeOfOptionalHeader = uint16(binary.Size(&oh64))
-		fh.Characteristics |= pe.IMAGE_FILE_LARGE_ADDRESS_AWARE
-	} else {
-		var oh pe.OptionalHeader32
-		fh.SizeOfOptionalHeader = uint16(binary.Size(&oh))
-		fh.Characteristics |= pe.IMAGE_FILE_32BIT_MACHINE
-	}
-
-	fh.PointerToSymbolTable = uint32(f.symtabOffset)
-	fh.NumberOfSymbols = uint32(f.symbolCount)
-
-	binary.Write(ctxt.Out, binary.LittleEndian, &fh)
-}
-
-// writeOptionalHeader writes COFF optional header for peFile f.
-func (f *peFile) writeOptionalHeader(ctxt *Link) {
-	var oh pe.OptionalHeader32
-	var oh64 pe.OptionalHeader64
-
-	if pe64 != 0 {
-		oh64.Magic = 0x20b // PE32+
-	} else {
-		oh.Magic = 0x10b // PE32
-		oh.BaseOfData = f.dataSect.virtualAddress
-	}
-
-	// Fill out both oh64 and oh. We only use one. Oh well.
-	oh64.MajorLinkerVersion = 3
-	oh.MajorLinkerVersion = 3
-	oh64.MinorLinkerVersion = 0
-	oh.MinorLinkerVersion = 0
-	oh64.SizeOfCode = f.textSect.sizeOfRawData
-	oh.SizeOfCode = f.textSect.sizeOfRawData
-	oh64.SizeOfInitializedData = f.dataSect.sizeOfRawData
-	oh.SizeOfInitializedData = f.dataSect.sizeOfRawData
-	oh64.SizeOfUninitializedData = 0
-	oh.SizeOfUninitializedData = 0
-	if ctxt.LinkMode != LinkExternal {
-		oh64.AddressOfEntryPoint = uint32(Entryvalue(ctxt) - PEBASE)
-		oh.AddressOfEntryPoint = uint32(Entryvalue(ctxt) - PEBASE)
-	}
-	oh64.BaseOfCode = f.textSect.virtualAddress
-	oh.BaseOfCode = f.textSect.virtualAddress
-	oh64.ImageBase = PEBASE
-	oh.ImageBase = PEBASE
-	oh64.SectionAlignment = uint32(PESECTALIGN)
-	oh.SectionAlignment = uint32(PESECTALIGN)
-	oh64.FileAlignment = uint32(PEFILEALIGN)
-	oh.FileAlignment = uint32(PEFILEALIGN)
-	oh64.MajorOperatingSystemVersion = PeMinimumTargetMajorVersion
-	oh.MajorOperatingSystemVersion = PeMinimumTargetMajorVersion
-	oh64.MinorOperatingSystemVersion = PeMinimumTargetMinorVersion
-	oh.MinorOperatingSystemVersion = PeMinimumTargetMinorVersion
-	oh64.MajorImageVersion = 1
-	oh.MajorImageVersion = 1
-	oh64.MinorImageVersion = 0
-	oh.MinorImageVersion = 0
-	oh64.MajorSubsystemVersion = PeMinimumTargetMajorVersion
-	oh.MajorSubsystemVersion = PeMinimumTargetMajorVersion
-	oh64.MinorSubsystemVersion = PeMinimumTargetMinorVersion
-	oh.MinorSubsystemVersion = PeMinimumTargetMinorVersion
-	oh64.SizeOfImage = f.nextSectOffset
-	oh.SizeOfImage = f.nextSectOffset
-	oh64.SizeOfHeaders = uint32(PEFILEHEADR)
-	oh.SizeOfHeaders = uint32(PEFILEHEADR)
-	if windowsgui {
-		oh64.Subsystem = pe.IMAGE_SUBSYSTEM_WINDOWS_GUI
-		oh.Subsystem = pe.IMAGE_SUBSYSTEM_WINDOWS_GUI
-	} else {
-		oh64.Subsystem = pe.IMAGE_SUBSYSTEM_WINDOWS_CUI
-		oh.Subsystem = pe.IMAGE_SUBSYSTEM_WINDOWS_CUI
-	}
-
-	// Mark as having awareness of terminal services, to avoid ancient compatibility hacks.
-	oh64.DllCharacteristics |= pe.IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
-	oh.DllCharacteristics |= pe.IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
-
-	// Enable DEP
-	oh64.DllCharacteristics |= pe.IMAGE_DLLCHARACTERISTICS_NX_COMPAT
-	oh.DllCharacteristics |= pe.IMAGE_DLLCHARACTERISTICS_NX_COMPAT
-
-	// The DLL can be relocated at load time.
-	switch ctxt.Arch.Family {
-	case sys.AMD64, sys.I386:
-		if ctxt.BuildMode == BuildModePIE {
-			oh64.DllCharacteristics |= pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
-			oh.DllCharacteristics |= pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
-		}
-	case sys.ARM:
-		oh64.DllCharacteristics |= pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
-		oh.DllCharacteristics |= pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
-	}
-
-	// Image can handle a high entropy 64-bit virtual address space.
-	if ctxt.BuildMode == BuildModePIE {
-		oh64.DllCharacteristics |= pe.IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA
-	}
-
-	// Disable stack growth as we don't want Windows to
-	// fiddle with the thread stack limits, which we set
-	// ourselves to circumvent the stack checks in the
-	// Windows exception dispatcher.
-	// Commit size must be strictly less than reserve
-	// size otherwise reserve will be rounded up to a
-	// larger size, as verified with VMMap.
-
-	// On 64-bit, we always reserve 2MB stacks. "Pure" Go code is
-	// okay with much smaller stacks, but the syscall package
-	// makes it easy to call into arbitrary C code without cgo,
-	// and system calls even in "pure" Go code are actually C
-	// calls that may need more stack than we think.
-	//
-	// The default stack reserve size directly affects only the main
-	// thread, ctrlhandler thread, and profileloop thread. For
-	// these, it must be greater than the stack size assumed by
-	// externalthreadhandler.
-	//
-	// For other threads, the runtime explicitly asks the kernel
-	// to use the default stack size so that all stacks are
-	// consistent.
-	//
-	// At thread start, in minit, the runtime queries the OS for
-	// the actual stack bounds so that the stack size doesn't need
-	// to be hard-coded into the runtime.
-	oh64.SizeOfStackReserve = 0x00200000
-	if !iscgo {
-		oh64.SizeOfStackCommit = 0x00001000
-	} else {
-		// TODO(brainman): Maybe remove optional header writing altogether for cgo.
-		// For cgo it is the external linker that is building final executable.
-		// And it probably does not use any information stored in optional header.
-		oh64.SizeOfStackCommit = 0x00200000 - 0x2000 // account for 2 guard pages
-	}
-
-	oh.SizeOfStackReserve = 0x00100000
-	if !iscgo {
-		oh.SizeOfStackCommit = 0x00001000
-	} else {
-		oh.SizeOfStackCommit = 0x00100000 - 0x2000 // account for 2 guard pages
-	}
-
-	oh64.SizeOfHeapReserve = 0x00100000
-	oh.SizeOfHeapReserve = 0x00100000
-	oh64.SizeOfHeapCommit = 0x00001000
-	oh.SizeOfHeapCommit = 0x00001000
-	oh64.NumberOfRvaAndSizes = 16
-	oh.NumberOfRvaAndSizes = 16
-
-	if pe64 != 0 {
-		oh64.DataDirectory = f.dataDirectory
-	} else {
-		oh.DataDirectory = f.dataDirectory
-	}
-
-	if pe64 != 0 {
-		binary.Write(ctxt.Out, binary.LittleEndian, &oh64)
-	} else {
-		binary.Write(ctxt.Out, binary.LittleEndian, &oh)
-	}
-}
-
-var pefile peFile
-
-func Peinit(ctxt *Link) {
-	var l int
-
-	switch ctxt.Arch.Family {
-	// 64-bit architectures
-	case sys.AMD64:
-		pe64 = 1
-		var oh64 pe.OptionalHeader64
-		l = binary.Size(&oh64)
-
-	// 32-bit architectures
-	default:
-		var oh pe.OptionalHeader32
-		l = binary.Size(&oh)
-
-	}
-
-	if ctxt.LinkMode == LinkExternal {
-		// .rdata section will contain "masks" and "shifts" symbols, and they
-		// need to be aligned to 16-bytes. So make all sections aligned
-		// to 32-byte and mark them all IMAGE_SCN_ALIGN_32BYTES so external
-		// linker will honour that requirement.
-		PESECTALIGN = 32
-		PEFILEALIGN = 0
-	}
-
-	var sh [16]pe.SectionHeader32
-	var fh pe.FileHeader
-	PEFILEHEADR = int32(Rnd(int64(len(dosstub)+binary.Size(&fh)+l+binary.Size(&sh)), PEFILEALIGN))
-	if ctxt.LinkMode != LinkExternal {
-		PESECTHEADR = int32(Rnd(int64(PEFILEHEADR), PESECTALIGN))
-	} else {
-		PESECTHEADR = 0
-	}
-	pefile.nextSectOffset = uint32(PESECTHEADR)
-	pefile.nextFileOffset = uint32(PEFILEHEADR)
-
-	if ctxt.LinkMode == LinkInternal {
-		// some mingw libs depend on this symbol, for example, FindPESectionByName
-		ctxt.xdefine("__image_base__", sym.SDATA, PEBASE)
-		ctxt.xdefine("_image_base__", sym.SDATA, PEBASE)
-	}
-
-	HEADR = PEFILEHEADR
-	if *FlagTextAddr == -1 {
-		*FlagTextAddr = PEBASE + int64(PESECTHEADR)
-	}
-	if *FlagRound == -1 {
-		*FlagRound = int(PESECTALIGN)
-	}
-}
-
-func pewrite(ctxt *Link) {
-	ctxt.Out.SeekSet(0)
-	if ctxt.LinkMode != LinkExternal {
-		ctxt.Out.Write(dosstub)
-		ctxt.Out.WriteStringN("PE", 4)
-	}
-
-	pefile.writeFileHeader(ctxt)
-
-	pefile.writeOptionalHeader(ctxt)
-
-	for _, sect := range pefile.sections {
-		sect.write(ctxt.Out, ctxt.LinkMode)
-	}
-}
-
-func strput(out *OutBuf, s string) {
-	out.WriteString(s)
-	out.Write8(0)
-	// string must be padded to even size
-	if (len(s)+1)%2 != 0 {
-		out.Write8(0)
-	}
-}
-
-func initdynimport(ctxt *Link) *Dll {
-	var d *Dll
-
-	dr = nil
-	var m *Imp
-	for _, s := range ctxt.Syms.Allsym {
-		if !s.Attr.Reachable() || s.Type != sym.SDYNIMPORT {
-			continue
-		}
-		for d = dr; d != nil; d = d.next {
-			if d.name == s.Dynimplib() {
-				m = new(Imp)
-				break
-			}
-		}
-
-		if d == nil {
-			d = new(Dll)
-			d.name = s.Dynimplib()
-			d.next = dr
-			dr = d
-			m = new(Imp)
-		}
-
-		// Because external link requires properly stdcall decorated name,
-		// all external symbols in runtime use %n to denote that the number
-		// of uinptrs this function consumes. Store the argsize and discard
-		// the %n suffix if any.
-		m.argsize = -1
-		extName := s.Extname()
-		if i := strings.IndexByte(extName, '%'); i >= 0 {
-			var err error
-			m.argsize, err = strconv.Atoi(extName[i+1:])
-			if err != nil {
-				Errorf(s, "failed to parse stdcall decoration: %v", err)
-			}
-			m.argsize *= ctxt.Arch.PtrSize
-			s.SetExtname(extName[:i])
-		}
-
-		m.s = s
-		m.next = d.ms
-		d.ms = m
-	}
-
-	if ctxt.LinkMode == LinkExternal {
-		// Add real symbol name
-		for d := dr; d != nil; d = d.next {
-			for m = d.ms; m != nil; m = m.next {
-				m.s.Type = sym.SDATA
-				m.s.Grow(int64(ctxt.Arch.PtrSize))
-				dynName := m.s.Extname()
-				// only windows/386 requires stdcall decoration
-				if ctxt.Arch.Family == sys.I386 && m.argsize >= 0 {
-					dynName += fmt.Sprintf("@%d", m.argsize)
-				}
-				dynSym := ctxt.Syms.Lookup(dynName, 0)
-				dynSym.Attr |= sym.AttrReachable
-				dynSym.Type = sym.SHOSTOBJ
-				r := m.s.AddRel()
-				r.Sym = dynSym
-				r.Off = 0
-				r.Siz = uint8(ctxt.Arch.PtrSize)
-				r.Type = objabi.R_ADDR
-			}
-		}
-	} else {
-		dynamic := ctxt.Syms.Lookup(".windynamic", 0)
-		dynamic.Attr |= sym.AttrReachable
-		dynamic.Type = sym.SWINDOWS
-		for d := dr; d != nil; d = d.next {
-			for m = d.ms; m != nil; m = m.next {
-				m.s.Type = sym.SWINDOWS
-				m.s.Attr |= sym.AttrSubSymbol
-				m.s.Sub = dynamic.Sub
-				dynamic.Sub = m.s
-				m.s.Value = dynamic.Size
-				dynamic.Size += int64(ctxt.Arch.PtrSize)
-			}
-
-			dynamic.Size += int64(ctxt.Arch.PtrSize)
-		}
-	}
-
-	return dr
-}
-
-// peimporteddlls returns the gcc command line argument to link all imported
-// DLLs.
-func peimporteddlls() []string {
-	var dlls []string
-
-	for d := dr; d != nil; d = d.next {
-		dlls = append(dlls, "-l"+strings.TrimSuffix(d.name, ".dll"))
-	}
-
-	return dlls
-}
-
-func addimports(ctxt *Link, datsect *peSection) {
-	startoff := ctxt.Out.Offset()
-	dynamic := ctxt.Syms.Lookup(".windynamic", 0)
-
-	// skip import descriptor table (will write it later)
-	n := uint64(0)
-
-	for d := dr; d != nil; d = d.next {
-		n++
-	}
-	ctxt.Out.SeekSet(startoff + int64(binary.Size(&IMAGE_IMPORT_DESCRIPTOR{}))*int64(n+1))
-
-	// write dll names
-	for d := dr; d != nil; d = d.next {
-		d.nameoff = uint64(ctxt.Out.Offset()) - uint64(startoff)
-		strput(ctxt.Out, d.name)
-	}
-
-	// write function names
-	for d := dr; d != nil; d = d.next {
-		for m := d.ms; m != nil; m = m.next {
-			m.off = uint64(pefile.nextSectOffset) + uint64(ctxt.Out.Offset()) - uint64(startoff)
-			ctxt.Out.Write16(0) // hint
-			strput(ctxt.Out, m.s.Extname())
-		}
-	}
-
-	// write OriginalFirstThunks
-	oftbase := uint64(ctxt.Out.Offset()) - uint64(startoff)
-
-	n = uint64(ctxt.Out.Offset())
-	for d := dr; d != nil; d = d.next {
-		d.thunkoff = uint64(ctxt.Out.Offset()) - n
-		for m := d.ms; m != nil; m = m.next {
-			if pe64 != 0 {
-				ctxt.Out.Write64(m.off)
-			} else {
-				ctxt.Out.Write32(uint32(m.off))
-			}
-		}
-
-		if pe64 != 0 {
-			ctxt.Out.Write64(0)
-		} else {
-			ctxt.Out.Write32(0)
-		}
-	}
-
-	// add pe section and pad it at the end
-	n = uint64(ctxt.Out.Offset()) - uint64(startoff)
-
-	isect := pefile.addSection(".idata", int(n), int(n))
-	isect.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
-	isect.checkOffset(startoff)
-	isect.pad(ctxt.Out, uint32(n))
-	endoff := ctxt.Out.Offset()
-
-	// write FirstThunks (allocated in .data section)
-	ftbase := uint64(dynamic.Value) - uint64(datsect.virtualAddress) - PEBASE
-
-	ctxt.Out.SeekSet(int64(uint64(datsect.pointerToRawData) + ftbase))
-	for d := dr; d != nil; d = d.next {
-		for m := d.ms; m != nil; m = m.next {
-			if pe64 != 0 {
-				ctxt.Out.Write64(m.off)
-			} else {
-				ctxt.Out.Write32(uint32(m.off))
-			}
-		}
-
-		if pe64 != 0 {
-			ctxt.Out.Write64(0)
-		} else {
-			ctxt.Out.Write32(0)
-		}
-	}
-
-	// finally write import descriptor table
-	out := ctxt.Out
-	out.SeekSet(startoff)
-
-	for d := dr; d != nil; d = d.next {
-		out.Write32(uint32(uint64(isect.virtualAddress) + oftbase + d.thunkoff))
-		out.Write32(0)
-		out.Write32(0)
-		out.Write32(uint32(uint64(isect.virtualAddress) + d.nameoff))
-		out.Write32(uint32(uint64(datsect.virtualAddress) + ftbase + d.thunkoff))
-	}
-
-	out.Write32(0) //end
-	out.Write32(0)
-	out.Write32(0)
-	out.Write32(0)
-	out.Write32(0)
-
-	// update data directory
-	pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = isect.virtualAddress
-	pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect.virtualSize
-	pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = uint32(dynamic.Value - PEBASE)
-	pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_IAT].Size = uint32(dynamic.Size)
-
-	out.SeekSet(endoff)
-}
-
-type byExtname []*sym.Symbol
-
-func (s byExtname) Len() int           { return len(s) }
-func (s byExtname) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-func (s byExtname) Less(i, j int) bool { return s[i].Extname() < s[j].Extname() }
-
-func initdynexport(ctxt *Link) {
-	nexport = 0
-	for _, s := range ctxt.Syms.Allsym {
-		if !s.Attr.Reachable() || !s.Attr.CgoExportDynamic() {
-			continue
-		}
-		if nexport+1 > len(dexport) {
-			Errorf(s, "pe dynexport table is full")
-			errorexit()
-		}
-
-		dexport[nexport] = s
-		nexport++
-	}
-
-	sort.Sort(byExtname(dexport[:nexport]))
-}
-
-func addexports(ctxt *Link) {
-	var e IMAGE_EXPORT_DIRECTORY
-
-	size := binary.Size(&e) + 10*nexport + len(*flagOutfile) + 1
-	for i := 0; i < nexport; i++ {
-		size += len(dexport[i].Extname()) + 1
-	}
-
-	if nexport == 0 {
-		return
-	}
-
-	sect := pefile.addSection(".edata", size, size)
-	sect.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
-	sect.checkOffset(ctxt.Out.Offset())
-	va := int(sect.virtualAddress)
-	pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = uint32(va)
-	pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect.virtualSize
-
-	vaName := va + binary.Size(&e) + nexport*4
-	vaAddr := va + binary.Size(&e)
-	vaNa := va + binary.Size(&e) + nexport*8
-
-	e.Characteristics = 0
-	e.MajorVersion = 0
-	e.MinorVersion = 0
-	e.NumberOfFunctions = uint32(nexport)
-	e.NumberOfNames = uint32(nexport)
-	e.Name = uint32(va+binary.Size(&e)) + uint32(nexport)*10 // Program names.
-	e.Base = 1
-	e.AddressOfFunctions = uint32(vaAddr)
-	e.AddressOfNames = uint32(vaName)
-	e.AddressOfNameOrdinals = uint32(vaNa)
-
-	out := ctxt.Out
-
-	// put IMAGE_EXPORT_DIRECTORY
-	binary.Write(out, binary.LittleEndian, &e)
-
-	// put EXPORT Address Table
-	for i := 0; i < nexport; i++ {
-		out.Write32(uint32(dexport[i].Value - PEBASE))
-	}
-
-	// put EXPORT Name Pointer Table
-	v := int(e.Name + uint32(len(*flagOutfile)) + 1)
-
-	for i := 0; i < nexport; i++ {
-		out.Write32(uint32(v))
-		v += len(dexport[i].Extname()) + 1
-	}
-
-	// put EXPORT Ordinal Table
-	for i := 0; i < nexport; i++ {
-		out.Write16(uint16(i))
-	}
-
-	// put Names
-	out.WriteStringN(*flagOutfile, len(*flagOutfile)+1)
-
-	for i := 0; i < nexport; i++ {
-		out.WriteStringN(dexport[i].Extname(), len(dexport[i].Extname())+1)
-	}
-	sect.pad(out, uint32(size))
-}
-
-// peBaseRelocEntry represents a single relocation entry.
-type peBaseRelocEntry struct {
-	typeOff uint16
-	rel     *sym.Reloc
-	sym     *sym.Symbol // For debug
-}
-
-// peBaseRelocBlock represents a Base Relocation Block. A block
-// is a collection of relocation entries in a page, where each
-// entry describes a single relocation.
-// The block page RVA (Relative Virtual Address) is the index
-// into peBaseRelocTable.blocks.
-type peBaseRelocBlock struct {
-	entries []peBaseRelocEntry
-}
-
-// pePages is a type used to store the list of pages for which there
-// are base relocation blocks. This is defined as a type so that
-// it can be sorted.
-type pePages []uint32
-
-func (p pePages) Len() int           { return len(p) }
-func (p pePages) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-func (p pePages) Less(i, j int) bool { return p[i] < p[j] }
-
-// A PE base relocation table is a list of blocks, where each block
-// contains relocation information for a single page. The blocks
-// must be emitted in order of page virtual address.
-// See https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format#the-reloc-section-image-only
-type peBaseRelocTable struct {
-	blocks map[uint32]peBaseRelocBlock
-
-	// pePages is a list of keys into blocks map.
-	// It is stored separately for ease of sorting.
-	pages pePages
-}
-
-func (rt *peBaseRelocTable) init(ctxt *Link) {
-	rt.blocks = make(map[uint32]peBaseRelocBlock)
-}
-
-func (rt *peBaseRelocTable) addentry(ctxt *Link, s *sym.Symbol, r *sym.Reloc) {
-	// pageSize is the size in bytes of a page
-	// described by a base relocation block.
-	const pageSize = 0x1000
-	const pageMask = pageSize - 1
-
-	addr := s.Value + int64(r.Off) - int64(PEBASE)
-	page := uint32(addr &^ pageMask)
-	off := uint32(addr & pageMask)
-
-	b, ok := rt.blocks[page]
-	if !ok {
-		rt.pages = append(rt.pages, page)
-	}
-
-	e := peBaseRelocEntry{
-		typeOff: uint16(off & 0xFFF),
-		rel:     r,
-		sym:     s,
-	}
-
-	// Set entry type
-	switch r.Siz {
-	default:
-		Exitf("unsupported relocation size %d\n", r.Siz)
-	case 4:
-		e.typeOff |= uint16(IMAGE_REL_BASED_HIGHLOW << 12)
-	case 8:
-		e.typeOff |= uint16(IMAGE_REL_BASED_DIR64 << 12)
-	}
-
-	b.entries = append(b.entries, e)
-	rt.blocks[page] = b
-}
-
-func (rt *peBaseRelocTable) write(ctxt *Link) {
-	out := ctxt.Out
-
-	// sort the pages array
-	sort.Sort(rt.pages)
-
-	for _, p := range rt.pages {
-		b := rt.blocks[p]
-		const sizeOfPEbaseRelocBlock = 8 // 2 * sizeof(uint32)
-		blockSize := uint32(sizeOfPEbaseRelocBlock + len(b.entries)*2)
-		out.Write32(p)
-		out.Write32(blockSize)
-
-		for _, e := range b.entries {
-			out.Write16(e.typeOff)
-		}
-	}
-}
-
-func addPEBaseRelocSym(ctxt *Link, s *sym.Symbol, rt *peBaseRelocTable) {
-	for ri := 0; ri < len(s.R); ri++ {
-		r := &s.R[ri]
-
-		if r.Sym == nil {
-			continue
-		}
-		if !r.Sym.Attr.Reachable() {
-			continue
-		}
-		if r.Type >= objabi.ElfRelocOffset {
-			continue
-		}
-		if r.Siz == 0 { // informational relocation
-			continue
-		}
-		if r.Type == objabi.R_DWARFFILEREF {
-			continue
-		}
-
-		switch r.Type {
-		default:
-		case objabi.R_ADDR:
-			rt.addentry(ctxt, s, r)
-		}
-	}
-}
-
-func addPEBaseReloc(ctxt *Link) {
-	// Arm does not work without base relocation table.
-	// 386 and amd64 will only require the table for BuildModePIE.
-	switch ctxt.Arch.Family {
-	default:
-		return
-	case sys.I386, sys.AMD64:
-		if ctxt.BuildMode != BuildModePIE {
-			return
-		}
-	case sys.ARM:
-	}
-
-	var rt peBaseRelocTable
-	rt.init(ctxt)
-
-	// Get relocation information
-	for _, s := range ctxt.Textp {
-		addPEBaseRelocSym(ctxt, s, &rt)
-	}
-	for _, s := range datap {
-		addPEBaseRelocSym(ctxt, s, &rt)
-	}
-
-	// Write relocation information
-	startoff := ctxt.Out.Offset()
-	rt.write(ctxt)
-	size := ctxt.Out.Offset() - startoff
-
-	// Add a PE section and pad it at the end
-	rsect := pefile.addSection(".reloc", int(size), int(size))
-	rsect.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
-	rsect.checkOffset(startoff)
-	rsect.pad(ctxt.Out, uint32(size))
-
-	pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = rsect.virtualAddress
-	pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = rsect.virtualSize
-}
-
-func (ctxt *Link) dope() {
-	initdynimport(ctxt)
-	initdynexport(ctxt)
-}
-
-func setpersrc(ctxt *Link, sym *sym.Symbol) {
-	if rsrcsym != nil {
-		Errorf(sym, "too many .rsrc sections")
-	}
-
-	rsrcsym = sym
-}
-
-func addpersrc(ctxt *Link) {
-	if rsrcsym == nil {
-		return
-	}
-
-	h := pefile.addSection(".rsrc", int(rsrcsym.Size), int(rsrcsym.Size))
-	h.characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_INITIALIZED_DATA
-	h.checkOffset(ctxt.Out.Offset())
-
-	// relocation
-	for ri := range rsrcsym.R {
-		r := &rsrcsym.R[ri]
-		p := rsrcsym.P[r.Off:]
-		val := uint32(int64(h.virtualAddress) + r.Add)
-
-		// 32-bit little-endian
-		p[0] = byte(val)
-
-		p[1] = byte(val >> 8)
-		p[2] = byte(val >> 16)
-		p[3] = byte(val >> 24)
-	}
-
-	ctxt.Out.Write(rsrcsym.P)
-	h.pad(ctxt.Out, uint32(rsrcsym.Size))
-
-	// update data directory
-	pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = h.virtualAddress
-
-	pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = h.virtualSize
-}
-
-func Asmbpe(ctxt *Link) {
-	switch ctxt.Arch.Family {
-	default:
-		Exitf("unknown PE architecture: %v", ctxt.Arch.Family)
-	case sys.AMD64, sys.I386, sys.ARM:
-	}
-
-	t := pefile.addSection(".text", int(Segtext.Length), int(Segtext.Length))
-	t.characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
-	if ctxt.LinkMode == LinkExternal {
-		// some data symbols (e.g. masks) end up in the .text section, and they normally
-		// expect larger alignment requirement than the default text section alignment.
-		t.characteristics |= IMAGE_SCN_ALIGN_32BYTES
-	}
-	t.checkSegment(&Segtext)
-	pefile.textSect = t
-
-	ro := pefile.addSection(".rdata", int(Segrodata.Length), int(Segrodata.Length))
-	ro.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
-	if ctxt.LinkMode == LinkExternal {
-		// some data symbols (e.g. masks) end up in the .rdata section, and they normally
-		// expect larger alignment requirement than the default text section alignment.
-		ro.characteristics |= IMAGE_SCN_ALIGN_32BYTES
-	}
-	ro.checkSegment(&Segrodata)
-	pefile.rdataSect = ro
-
-	var d *peSection
-	if ctxt.LinkMode != LinkExternal {
-		d = pefile.addSection(".data", int(Segdata.Length), int(Segdata.Filelen))
-		d.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
-		d.checkSegment(&Segdata)
-		pefile.dataSect = d
-	} else {
-		d = pefile.addSection(".data", int(Segdata.Filelen), int(Segdata.Filelen))
-		d.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_ALIGN_32BYTES
-		d.checkSegment(&Segdata)
-		pefile.dataSect = d
-
-		b := pefile.addSection(".bss", int(Segdata.Length-Segdata.Filelen), 0)
-		b.characteristics = IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_ALIGN_32BYTES
-		b.pointerToRawData = 0
-		pefile.bssSect = b
-	}
-
-	pefile.addDWARF()
-
-	if ctxt.LinkMode == LinkExternal {
-		pefile.ctorsSect = pefile.addInitArray(ctxt)
-	}
-
-	ctxt.Out.SeekSet(int64(pefile.nextFileOffset))
-	if ctxt.LinkMode != LinkExternal {
-		addimports(ctxt, d)
-		addexports(ctxt)
-		addPEBaseReloc(ctxt)
-	}
-	pefile.writeSymbolTableAndStringTable(ctxt)
-	addpersrc(ctxt)
-	if ctxt.LinkMode == LinkExternal {
-		pefile.emitRelocations(ctxt)
-	}
-
-	pewrite(ctxt)
-}
diff --git a/src/cmd/oldlink/internal/ld/sym.go b/src/cmd/oldlink/internal/ld/sym.go
deleted file mode 100644
index 4f697d0..0000000
--- a/src/cmd/oldlink/internal/ld/sym.go
+++ /dev/null
@@ -1,109 +0,0 @@
-// Derived from Inferno utils/6l/obj.c and utils/6l/span.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ld
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/sym"
-	"log"
-)
-
-func linknew(arch *sys.Arch) *Link {
-	ctxt := &Link{
-		Syms:         sym.NewSymbols(),
-		Out:          &OutBuf{arch: arch},
-		Arch:         arch,
-		LibraryByPkg: make(map[string]*sym.Library),
-	}
-
-	if objabi.GOARCH != arch.Name {
-		log.Fatalf("invalid objabi.GOARCH %s (want %s)", objabi.GOARCH, arch.Name)
-	}
-
-	AtExit(func() {
-		if nerrors > 0 && ctxt.Out.f != nil {
-			ctxt.Out.f.Close()
-			mayberemoveoutfile()
-		}
-	})
-
-	return ctxt
-}
-
-// computeTLSOffset records the thread-local storage offset.
-// Not used for Android where the TLS offset is determined at runtime.
-func (ctxt *Link) computeTLSOffset() {
-	switch ctxt.HeadType {
-	default:
-		log.Fatalf("unknown thread-local storage offset for %v", ctxt.HeadType)
-
-	case objabi.Hplan9, objabi.Hwindows, objabi.Hjs, objabi.Haix:
-		break
-
-	case objabi.Hlinux,
-		objabi.Hfreebsd,
-		objabi.Hnetbsd,
-		objabi.Hopenbsd,
-		objabi.Hdragonfly,
-		objabi.Hsolaris:
-		/*
-		 * ELF uses TLS offset negative from FS.
-		 * Translate 0(FS) and 8(FS) into -16(FS) and -8(FS).
-		 * Known to low-level assembly in package runtime and runtime/cgo.
-		 */
-		ctxt.Tlsoffset = -1 * ctxt.Arch.PtrSize
-
-	case objabi.Hdarwin:
-		/*
-		 * OS X system constants - offset from 0(GS) to our TLS.
-		 */
-		switch ctxt.Arch.Family {
-		default:
-			log.Fatalf("unknown thread-local storage offset for darwin/%s", ctxt.Arch.Name)
-
-			/*
-			 * For x86, Apple has reserved a slot in the TLS for Go. See issue 23617.
-			 * That slot is at offset 0x30 on amd64.
-			 * The slot will hold the G pointer.
-			 * These constants should match those in runtime/sys_darwin_{386,amd64}.s
-			 * and runtime/cgo/gcc_darwin_{386,amd64}.c.
-			 */
-		case sys.AMD64:
-			ctxt.Tlsoffset = 0x30
-
-		case sys.ARM64:
-			ctxt.Tlsoffset = 0 // dummy value, not needed
-		}
-	}
-
-}
diff --git a/src/cmd/oldlink/internal/ld/symtab.go b/src/cmd/oldlink/internal/ld/symtab.go
deleted file mode 100644
index a324fdf..0000000
--- a/src/cmd/oldlink/internal/ld/symtab.go
+++ /dev/null
@@ -1,713 +0,0 @@
-// Inferno utils/6l/span.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ld
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/sym"
-	"fmt"
-	"path/filepath"
-	"strings"
-)
-
-// Symbol table.
-
-func putelfstr(s string) int {
-	if len(Elfstrdat) == 0 && s != "" {
-		// first entry must be empty string
-		putelfstr("")
-	}
-
-	off := len(Elfstrdat)
-	Elfstrdat = append(Elfstrdat, s...)
-	Elfstrdat = append(Elfstrdat, 0)
-	return off
-}
-
-func putelfsyment(out *OutBuf, off int, addr int64, size int64, info int, shndx int, other int) {
-	if elf64 {
-		out.Write32(uint32(off))
-		out.Write8(uint8(info))
-		out.Write8(uint8(other))
-		out.Write16(uint16(shndx))
-		out.Write64(uint64(addr))
-		out.Write64(uint64(size))
-		Symsize += ELF64SYMSIZE
-	} else {
-		out.Write32(uint32(off))
-		out.Write32(uint32(addr))
-		out.Write32(uint32(size))
-		out.Write8(uint8(info))
-		out.Write8(uint8(other))
-		out.Write16(uint16(shndx))
-		Symsize += ELF32SYMSIZE
-	}
-}
-
-var numelfsym = 1 // 0 is reserved
-
-var elfbind int
-
-func putelfsym(ctxt *Link, x *sym.Symbol, s string, t SymbolType, addr int64, go_ *sym.Symbol) {
-	var typ int
-
-	switch t {
-	default:
-		return
-
-	case TextSym:
-		typ = STT_FUNC
-
-	case DataSym, BSSSym:
-		typ = STT_OBJECT
-
-	case UndefinedSym:
-		// ElfType is only set for symbols read from Go shared libraries, but
-		// for other symbols it is left as STT_NOTYPE which is fine.
-		typ = int(x.ElfType())
-
-	case TLSSym:
-		typ = STT_TLS
-	}
-
-	size := x.Size
-	if t == UndefinedSym {
-		size = 0
-	}
-
-	xo := x
-	for xo.Outer != nil {
-		xo = xo.Outer
-	}
-
-	var elfshnum int
-	if xo.Type == sym.SDYNIMPORT || xo.Type == sym.SHOSTOBJ || xo.Type == sym.SUNDEFEXT {
-		elfshnum = SHN_UNDEF
-	} else {
-		if xo.Sect == nil {
-			Errorf(x, "missing section in putelfsym")
-			return
-		}
-		if xo.Sect.Elfsect == nil {
-			Errorf(x, "missing ELF section in putelfsym")
-			return
-		}
-		elfshnum = xo.Sect.Elfsect.(*ElfShdr).shnum
-	}
-
-	// One pass for each binding: STB_LOCAL, STB_GLOBAL,
-	// maybe one day STB_WEAK.
-	bind := STB_GLOBAL
-
-	if x.IsFileLocal() || x.Attr.VisibilityHidden() || x.Attr.Local() {
-		bind = STB_LOCAL
-	}
-
-	// In external linking mode, we have to invoke gcc with -rdynamic
-	// to get the exported symbols put into the dynamic symbol table.
-	// To avoid filling the dynamic table with lots of unnecessary symbols,
-	// mark all Go symbols local (not global) in the final executable.
-	// But when we're dynamically linking, we need all those global symbols.
-	if !ctxt.DynlinkingGo() && ctxt.LinkMode == LinkExternal && !x.Attr.CgoExportStatic() && elfshnum != SHN_UNDEF {
-		bind = STB_LOCAL
-	}
-
-	if ctxt.LinkMode == LinkExternal && elfshnum != SHN_UNDEF {
-		addr -= int64(xo.Sect.Vaddr)
-	}
-	other := STV_DEFAULT
-	if x.Attr.VisibilityHidden() {
-		// TODO(mwhudson): We only set AttrVisibilityHidden in ldelf, i.e. when
-		// internally linking. But STV_HIDDEN visibility only matters in object
-		// files and shared libraries, and as we are a long way from implementing
-		// internal linking for shared libraries and only create object files when
-		// externally linking, I don't think this makes a lot of sense.
-		other = STV_HIDDEN
-	}
-	if ctxt.Arch.Family == sys.PPC64 && typ == STT_FUNC && x.Attr.Shared() && x.Name != "runtime.duffzero" && x.Name != "runtime.duffcopy" {
-		// On ppc64 the top three bits of the st_other field indicate how
-		// many instructions separate the global and local entry points. In
-		// our case it is two instructions, indicated by the value 3.
-		// The conditions here match those in preprocess in
-		// cmd/internal/obj/ppc64/obj9.go, which is where the
-		// instructions are inserted.
-		other |= 3 << 5
-	}
-
-	// When dynamically linking, we create Symbols by reading the names from
-	// the symbol tables of the shared libraries and so the names need to
-	// match exactly. Tools like DTrace will have to wait for now.
-	if !ctxt.DynlinkingGo() {
-		// Rewrite · to . for ASCII-only tools like DTrace (sigh)
-		s = strings.Replace(s, "·", ".", -1)
-	}
-
-	if ctxt.DynlinkingGo() && bind == STB_GLOBAL && elfbind == STB_LOCAL && x.Type == sym.STEXT {
-		// When dynamically linking, we want references to functions defined
-		// in this module to always be to the function object, not to the
-		// PLT. We force this by writing an additional local symbol for every
-		// global function symbol and making all relocations against the
-		// global symbol refer to this local symbol instead (see
-		// (*sym.Symbol).ElfsymForReloc). This is approximately equivalent to the
-		// ELF linker -Bsymbolic-functions option, but that is buggy on
-		// several platforms.
-		putelfsyment(ctxt.Out, putelfstr("local."+s), addr, size, STB_LOCAL<<4|typ&0xf, elfshnum, other)
-		x.LocalElfsym = int32(numelfsym)
-		numelfsym++
-		return
-	} else if bind != elfbind {
-		return
-	}
-
-	putelfsyment(ctxt.Out, putelfstr(s), addr, size, bind<<4|typ&0xf, elfshnum, other)
-	x.Elfsym = int32(numelfsym)
-	numelfsym++
-}
-
-func putelfsectionsym(out *OutBuf, s *sym.Symbol, shndx int) {
-	putelfsyment(out, 0, 0, 0, STB_LOCAL<<4|STT_SECTION, shndx, 0)
-	s.Elfsym = int32(numelfsym)
-	numelfsym++
-}
-
-func Asmelfsym(ctxt *Link) {
-	// the first symbol entry is reserved
-	putelfsyment(ctxt.Out, 0, 0, 0, STB_LOCAL<<4|STT_NOTYPE, 0, 0)
-
-	dwarfaddelfsectionsyms(ctxt)
-
-	// Some linkers will add a FILE sym if one is not present.
-	// Avoid having the working directory inserted into the symbol table.
-	// It is added with a name to avoid problems with external linking
-	// encountered on some versions of Solaris. See issue #14957.
-	putelfsyment(ctxt.Out, putelfstr("go.go"), 0, 0, STB_LOCAL<<4|STT_FILE, SHN_ABS, 0)
-	numelfsym++
-
-	elfbind = STB_LOCAL
-	genasmsym(ctxt, putelfsym)
-
-	elfbind = STB_GLOBAL
-	elfglobalsymndx = numelfsym
-	genasmsym(ctxt, putelfsym)
-}
-
-func putplan9sym(ctxt *Link, x *sym.Symbol, s string, typ SymbolType, addr int64, go_ *sym.Symbol) {
-	t := int(typ)
-	switch typ {
-	case TextSym, DataSym, BSSSym:
-		if x.IsFileLocal() {
-			t += 'a' - 'A'
-		}
-		fallthrough
-
-	case AutoSym, ParamSym, FrameSym:
-		l := 4
-		if ctxt.HeadType == objabi.Hplan9 && ctxt.Arch.Family == sys.AMD64 && !Flag8 {
-			ctxt.Out.Write32b(uint32(addr >> 32))
-			l = 8
-		}
-
-		ctxt.Out.Write32b(uint32(addr))
-		ctxt.Out.Write8(uint8(t + 0x80)) /* 0x80 is variable length */
-
-		ctxt.Out.WriteString(s)
-		ctxt.Out.Write8(0)
-
-		Symsize += int32(l) + 1 + int32(len(s)) + 1
-
-	default:
-		return
-	}
-}
-
-func Asmplan9sym(ctxt *Link) {
-	genasmsym(ctxt, putplan9sym)
-}
-
-var symt *sym.Symbol
-
-type byPkg []*sym.Library
-
-func (libs byPkg) Len() int {
-	return len(libs)
-}
-
-func (libs byPkg) Less(a, b int) bool {
-	return libs[a].Pkg < libs[b].Pkg
-}
-
-func (libs byPkg) Swap(a, b int) {
-	libs[a], libs[b] = libs[b], libs[a]
-}
-
-// Create a table with information on the text sections.
-
-func textsectionmap(ctxt *Link) uint32 {
-
-	t := ctxt.Syms.Lookup("runtime.textsectionmap", 0)
-	t.Type = sym.SRODATA
-	t.Attr |= sym.AttrReachable
-	nsections := int64(0)
-
-	for _, sect := range Segtext.Sections {
-		if sect.Name == ".text" {
-			nsections++
-		} else {
-			break
-		}
-	}
-	t.Grow(3 * nsections * int64(ctxt.Arch.PtrSize))
-
-	off := int64(0)
-	n := 0
-
-	// The vaddr for each text section is the difference between the section's
-	// Vaddr and the Vaddr for the first text section as determined at compile
-	// time.
-
-	// The symbol for the first text section is named runtime.text as before.
-	// Additional text sections are named runtime.text.n where n is the
-	// order of creation starting with 1. These symbols provide the section's
-	// address after relocation by the linker.
-
-	textbase := Segtext.Sections[0].Vaddr
-	for _, sect := range Segtext.Sections {
-		if sect.Name != ".text" {
-			break
-		}
-		off = t.SetUint(ctxt.Arch, off, sect.Vaddr-textbase)
-		off = t.SetUint(ctxt.Arch, off, sect.Length)
-		if n == 0 {
-			s := ctxt.Syms.ROLookup("runtime.text", 0)
-			if s == nil {
-				Errorf(nil, "Unable to find symbol runtime.text\n")
-			}
-			off = t.SetAddr(ctxt.Arch, off, s)
-
-		} else {
-			s := ctxt.Syms.Lookup(fmt.Sprintf("runtime.text.%d", n), 0)
-			if s == nil {
-				Errorf(nil, "Unable to find symbol runtime.text.%d\n", n)
-			}
-			off = t.SetAddr(ctxt.Arch, off, s)
-		}
-		n++
-	}
-	return uint32(n)
-}
-
-func (ctxt *Link) symtab() {
-	switch ctxt.BuildMode {
-	case BuildModeCArchive, BuildModeCShared:
-		for _, s := range ctxt.Syms.Allsym {
-			// Create a new entry in the .init_array section that points to the
-			// library initializer function.
-			if s.Name == *flagEntrySymbol && ctxt.HeadType != objabi.Haix {
-				addinitarrdata(ctxt, s)
-			}
-		}
-	}
-
-	// Define these so that they'll get put into the symbol table.
-	// data.c:/^address will provide the actual values.
-	ctxt.xdefine("runtime.text", sym.STEXT, 0)
-
-	ctxt.xdefine("runtime.etext", sym.STEXT, 0)
-	ctxt.xdefine("runtime.itablink", sym.SRODATA, 0)
-	ctxt.xdefine("runtime.eitablink", sym.SRODATA, 0)
-	ctxt.xdefine("runtime.rodata", sym.SRODATA, 0)
-	ctxt.xdefine("runtime.erodata", sym.SRODATA, 0)
-	ctxt.xdefine("runtime.types", sym.SRODATA, 0)
-	ctxt.xdefine("runtime.etypes", sym.SRODATA, 0)
-	ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, 0)
-	ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, 0)
-	ctxt.xdefine("runtime.data", sym.SDATA, 0)
-	ctxt.xdefine("runtime.edata", sym.SDATA, 0)
-	ctxt.xdefine("runtime.bss", sym.SBSS, 0)
-	ctxt.xdefine("runtime.ebss", sym.SBSS, 0)
-	ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, 0)
-	ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, 0)
-	ctxt.xdefine("runtime.end", sym.SBSS, 0)
-	ctxt.xdefine("runtime.epclntab", sym.SRODATA, 0)
-	ctxt.xdefine("runtime.esymtab", sym.SRODATA, 0)
-
-	// garbage collection symbols
-	s := ctxt.Syms.Lookup("runtime.gcdata", 0)
-
-	s.Type = sym.SRODATA
-	s.Size = 0
-	s.Attr |= sym.AttrReachable
-	ctxt.xdefine("runtime.egcdata", sym.SRODATA, 0)
-
-	s = ctxt.Syms.Lookup("runtime.gcbss", 0)
-	s.Type = sym.SRODATA
-	s.Size = 0
-	s.Attr |= sym.AttrReachable
-	ctxt.xdefine("runtime.egcbss", sym.SRODATA, 0)
-
-	// pseudo-symbols to mark locations of type, string, and go string data.
-	var symtype *sym.Symbol
-	var symtyperel *sym.Symbol
-	if !ctxt.DynlinkingGo() {
-		if ctxt.UseRelro() && (ctxt.BuildMode == BuildModeCArchive || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE) {
-			s = ctxt.Syms.Lookup("type.*", 0)
-
-			s.Type = sym.STYPE
-			s.Size = 0
-			s.Attr |= sym.AttrReachable
-			symtype = s
-
-			s = ctxt.Syms.Lookup("typerel.*", 0)
-
-			s.Type = sym.STYPERELRO
-			s.Size = 0
-			s.Attr |= sym.AttrReachable
-			symtyperel = s
-		} else {
-			s = ctxt.Syms.Lookup("type.*", 0)
-
-			s.Type = sym.STYPE
-			s.Size = 0
-			s.Attr |= sym.AttrReachable
-			symtype = s
-			symtyperel = s
-		}
-	}
-
-	groupSym := func(name string, t sym.SymKind) *sym.Symbol {
-		s := ctxt.Syms.Lookup(name, 0)
-		s.Type = t
-		s.Size = 0
-		s.Attr |= sym.AttrLocal | sym.AttrReachable
-		return s
-	}
-	var (
-		symgostring = groupSym("go.string.*", sym.SGOSTRING)
-		symgofunc   = groupSym("go.func.*", sym.SGOFUNC)
-		symgcbits   = groupSym("runtime.gcbits.*", sym.SGCBITS)
-	)
-
-	var symgofuncrel *sym.Symbol
-	if !ctxt.DynlinkingGo() {
-		if ctxt.UseRelro() {
-			symgofuncrel = groupSym("go.funcrel.*", sym.SGOFUNCRELRO)
-		} else {
-			symgofuncrel = symgofunc
-		}
-	}
-
-	symitablink := ctxt.Syms.Lookup("runtime.itablink", 0)
-	symitablink.Type = sym.SITABLINK
-
-	symt = ctxt.Syms.Lookup("runtime.symtab", 0)
-	symt.Attr |= sym.AttrLocal
-	symt.Type = sym.SSYMTAB
-	symt.Size = 0
-	symt.Attr |= sym.AttrReachable
-
-	nitablinks := 0
-
-	// assign specific types so that they sort together.
-	// within a type they sort by size, so the .* symbols
-	// just defined above will be first.
-	// hide the specific symbols.
-	for _, s := range ctxt.Syms.Allsym {
-		if ctxt.LinkMode != LinkExternal && isStaticTemp(s.Name) {
-			s.Attr |= sym.AttrNotInSymbolTable
-		}
-
-		if !s.Attr.Reachable() || s.Attr.Special() || s.Type != sym.SRODATA {
-			continue
-		}
-
-		switch {
-		case strings.HasPrefix(s.Name, "type."):
-			if !ctxt.DynlinkingGo() {
-				s.Attr |= sym.AttrNotInSymbolTable
-			}
-			if ctxt.UseRelro() {
-				s.Type = sym.STYPERELRO
-				s.Outer = symtyperel
-			} else {
-				s.Type = sym.STYPE
-				s.Outer = symtype
-			}
-
-		case strings.HasPrefix(s.Name, "go.importpath.") && ctxt.UseRelro():
-			// Keep go.importpath symbols in the same section as types and
-			// names, as they can be referred to by a section offset.
-			s.Type = sym.STYPERELRO
-
-		case strings.HasPrefix(s.Name, "go.itablink."):
-			nitablinks++
-			s.Type = sym.SITABLINK
-			s.Attr |= sym.AttrNotInSymbolTable
-			s.Outer = symitablink
-
-		case strings.HasPrefix(s.Name, "go.string."):
-			s.Type = sym.SGOSTRING
-			s.Attr |= sym.AttrNotInSymbolTable
-			s.Outer = symgostring
-
-		case strings.HasPrefix(s.Name, "runtime.gcbits."):
-			s.Type = sym.SGCBITS
-			s.Attr |= sym.AttrNotInSymbolTable
-			s.Outer = symgcbits
-
-		case strings.HasSuffix(s.Name, "·f"):
-			if !ctxt.DynlinkingGo() {
-				s.Attr |= sym.AttrNotInSymbolTable
-			}
-			if ctxt.UseRelro() {
-				s.Type = sym.SGOFUNCRELRO
-				s.Outer = symgofuncrel
-			} else {
-				s.Type = sym.SGOFUNC
-				s.Outer = symgofunc
-			}
-
-		case strings.HasPrefix(s.Name, "gcargs."),
-			strings.HasPrefix(s.Name, "gclocals."),
-			strings.HasPrefix(s.Name, "gclocals·"),
-			strings.HasPrefix(s.Name, "inltree."),
-			strings.HasSuffix(s.Name, ".opendefer"):
-			s.Type = sym.SGOFUNC
-			s.Attr |= sym.AttrNotInSymbolTable
-			s.Outer = symgofunc
-			s.Align = 4
-			liveness += (s.Size + int64(s.Align) - 1) &^ (int64(s.Align) - 1)
-		}
-	}
-
-	if ctxt.BuildMode == BuildModeShared {
-		abihashgostr := ctxt.Syms.Lookup("go.link.abihash."+filepath.Base(*flagOutfile), 0)
-		abihashgostr.Attr |= sym.AttrReachable
-		abihashgostr.Type = sym.SRODATA
-		hashsym := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
-		abihashgostr.AddAddr(ctxt.Arch, hashsym)
-		abihashgostr.AddUint(ctxt.Arch, uint64(hashsym.Size))
-	}
-	if ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
-		for _, l := range ctxt.Library {
-			s := ctxt.Syms.Lookup("go.link.pkghashbytes."+l.Pkg, 0)
-			s.Attr |= sym.AttrReachable
-			s.Type = sym.SRODATA
-			s.Size = int64(len(l.Hash))
-			s.P = []byte(l.Hash)
-			str := ctxt.Syms.Lookup("go.link.pkghash."+l.Pkg, 0)
-			str.Attr |= sym.AttrReachable
-			str.Type = sym.SRODATA
-			str.AddAddr(ctxt.Arch, s)
-			str.AddUint(ctxt.Arch, uint64(len(l.Hash)))
-		}
-	}
-
-	nsections := textsectionmap(ctxt)
-
-	// Information about the layout of the executable image for the
-	// runtime to use. Any changes here must be matched by changes to
-	// the definition of moduledata in runtime/symtab.go.
-	// This code uses several global variables that are set by pcln.go:pclntab.
-	moduledata := ctxt.Moduledata
-	// The pclntab slice
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.pclntab", 0))
-	moduledata.AddUint(ctxt.Arch, uint64(ctxt.Syms.Lookup("runtime.pclntab", 0).Size))
-	moduledata.AddUint(ctxt.Arch, uint64(ctxt.Syms.Lookup("runtime.pclntab", 0).Size))
-	// The ftab slice
-	moduledata.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup("runtime.pclntab", 0), int64(pclntabPclntabOffset))
-	moduledata.AddUint(ctxt.Arch, uint64(pclntabNfunc+1))
-	moduledata.AddUint(ctxt.Arch, uint64(pclntabNfunc+1))
-	// The filetab slice
-	moduledata.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup("runtime.pclntab", 0), int64(pclntabFiletabOffset))
-	moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Filesyms))+1)
-	moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Filesyms))+1)
-	// findfunctab
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.findfunctab", 0))
-	// minpc, maxpc
-	moduledata.AddAddr(ctxt.Arch, pclntabFirstFunc)
-	moduledata.AddAddrPlus(ctxt.Arch, pclntabLastFunc, pclntabLastFunc.Size)
-	// pointers to specific parts of the module
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.text", 0))
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.etext", 0))
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.noptrdata", 0))
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.enoptrdata", 0))
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.data", 0))
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.edata", 0))
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.bss", 0))
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.ebss", 0))
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.noptrbss", 0))
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.enoptrbss", 0))
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.end", 0))
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.gcdata", 0))
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.gcbss", 0))
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.types", 0))
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.etypes", 0))
-
-	if ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal {
-		// Add R_REF relocation to prevent ld's garbage collection of
-		// runtime.rodata, runtime.erodata and runtime.epclntab.
-		addRef := func(name string) {
-			r := moduledata.AddRel()
-			r.Sym = ctxt.Syms.Lookup(name, 0)
-			r.Type = objabi.R_XCOFFREF
-			r.Siz = uint8(ctxt.Arch.PtrSize)
-		}
-		addRef("runtime.rodata")
-		addRef("runtime.erodata")
-		addRef("runtime.epclntab")
-	}
-
-	// text section information
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.textsectionmap", 0))
-	moduledata.AddUint(ctxt.Arch, uint64(nsections))
-	moduledata.AddUint(ctxt.Arch, uint64(nsections))
-
-	// The typelinks slice
-	typelinkSym := ctxt.Syms.Lookup("runtime.typelink", 0)
-	ntypelinks := uint64(typelinkSym.Size) / 4
-	moduledata.AddAddr(ctxt.Arch, typelinkSym)
-	moduledata.AddUint(ctxt.Arch, ntypelinks)
-	moduledata.AddUint(ctxt.Arch, ntypelinks)
-	// The itablinks slice
-	moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.itablink", 0))
-	moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
-	moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
-	// The ptab slice
-	if ptab := ctxt.Syms.ROLookup("go.plugin.tabs", 0); ptab != nil && ptab.Attr.Reachable() {
-		ptab.Attr |= sym.AttrLocal
-		ptab.Type = sym.SRODATA
-
-		nentries := uint64(len(ptab.P) / 8) // sizeof(nameOff) + sizeof(typeOff)
-		moduledata.AddAddr(ctxt.Arch, ptab)
-		moduledata.AddUint(ctxt.Arch, nentries)
-		moduledata.AddUint(ctxt.Arch, nentries)
-	} else {
-		moduledata.AddUint(ctxt.Arch, 0)
-		moduledata.AddUint(ctxt.Arch, 0)
-		moduledata.AddUint(ctxt.Arch, 0)
-	}
-	if ctxt.BuildMode == BuildModePlugin {
-		addgostring(ctxt, moduledata, "go.link.thispluginpath", objabi.PathToPrefix(*flagPluginPath))
-
-		pkghashes := ctxt.Syms.Lookup("go.link.pkghashes", 0)
-		pkghashes.Attr |= sym.AttrReachable
-		pkghashes.Attr |= sym.AttrLocal
-		pkghashes.Type = sym.SRODATA
-
-		for i, l := range ctxt.Library {
-			// pkghashes[i].name
-			addgostring(ctxt, pkghashes, fmt.Sprintf("go.link.pkgname.%d", i), l.Pkg)
-			// pkghashes[i].linktimehash
-			addgostring(ctxt, pkghashes, fmt.Sprintf("go.link.pkglinkhash.%d", i), l.Hash)
-			// pkghashes[i].runtimehash
-			hash := ctxt.Syms.ROLookup("go.link.pkghash."+l.Pkg, 0)
-			pkghashes.AddAddr(ctxt.Arch, hash)
-		}
-		moduledata.AddAddr(ctxt.Arch, pkghashes)
-		moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Library)))
-		moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Library)))
-	} else {
-		moduledata.AddUint(ctxt.Arch, 0) // pluginpath
-		moduledata.AddUint(ctxt.Arch, 0)
-		moduledata.AddUint(ctxt.Arch, 0) // pkghashes slice
-		moduledata.AddUint(ctxt.Arch, 0)
-		moduledata.AddUint(ctxt.Arch, 0)
-	}
-	if len(ctxt.Shlibs) > 0 {
-		thismodulename := filepath.Base(*flagOutfile)
-		switch ctxt.BuildMode {
-		case BuildModeExe, BuildModePIE:
-			// When linking an executable, outfile is just "a.out". Make
-			// it something slightly more comprehensible.
-			thismodulename = "the executable"
-		}
-		addgostring(ctxt, moduledata, "go.link.thismodulename", thismodulename)
-
-		modulehashes := ctxt.Syms.Lookup("go.link.abihashes", 0)
-		modulehashes.Attr |= sym.AttrReachable
-		modulehashes.Attr |= sym.AttrLocal
-		modulehashes.Type = sym.SRODATA
-
-		for i, shlib := range ctxt.Shlibs {
-			// modulehashes[i].modulename
-			modulename := filepath.Base(shlib.Path)
-			addgostring(ctxt, modulehashes, fmt.Sprintf("go.link.libname.%d", i), modulename)
-
-			// modulehashes[i].linktimehash
-			addgostring(ctxt, modulehashes, fmt.Sprintf("go.link.linkhash.%d", i), string(shlib.Hash))
-
-			// modulehashes[i].runtimehash
-			abihash := ctxt.Syms.Lookup("go.link.abihash."+modulename, 0)
-			abihash.Attr |= sym.AttrReachable
-			modulehashes.AddAddr(ctxt.Arch, abihash)
-		}
-
-		moduledata.AddAddr(ctxt.Arch, modulehashes)
-		moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Shlibs)))
-		moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Shlibs)))
-	} else {
-		moduledata.AddUint(ctxt.Arch, 0) // modulename
-		moduledata.AddUint(ctxt.Arch, 0)
-		moduledata.AddUint(ctxt.Arch, 0) // moduleshashes slice
-		moduledata.AddUint(ctxt.Arch, 0)
-		moduledata.AddUint(ctxt.Arch, 0)
-	}
-
-	hasmain := ctxt.BuildMode == BuildModeExe || ctxt.BuildMode == BuildModePIE
-	if hasmain {
-		moduledata.AddUint8(1)
-	} else {
-		moduledata.AddUint8(0)
-	}
-
-	// The rest of moduledata is zero initialized.
-	// When linking an object that does not contain the runtime we are
-	// creating the moduledata from scratch and it does not have a
-	// compiler-provided size, so read it from the type data.
-	moduledatatype := ctxt.Syms.ROLookup("type.runtime.moduledata", 0)
-	moduledata.Size = decodetypeSize(ctxt.Arch, moduledatatype.P)
-	moduledata.Grow(moduledata.Size)
-
-	lastmoduledatap := ctxt.Syms.Lookup("runtime.lastmoduledatap", 0)
-	if lastmoduledatap.Type != sym.SDYNIMPORT {
-		lastmoduledatap.Type = sym.SNOPTRDATA
-		lastmoduledatap.Size = 0 // overwrite existing value
-		lastmoduledatap.AddAddr(ctxt.Arch, moduledata)
-	}
-}
-
-func isStaticTemp(name string) bool {
-	if i := strings.LastIndex(name, "/"); i >= 0 {
-		name = name[i:]
-	}
-	return strings.Contains(name, "..stmp_")
-}
diff --git a/src/cmd/oldlink/internal/ld/testdata/httptest/main/main.go b/src/cmd/oldlink/internal/ld/testdata/httptest/main/main.go
deleted file mode 100644
index 1bce301..0000000
--- a/src/cmd/oldlink/internal/ld/testdata/httptest/main/main.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// A small test program that uses the net/http package. There is
-// nothing special about net/http here, this is just a convenient way
-// to pull in a lot of code.
-
-package main
-
-import (
-	"net/http"
-	"net/http/httptest"
-)
-
-type statusHandler int
-
-func (h *statusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	w.WriteHeader(int(*h))
-}
-
-func main() {
-	status := statusHandler(http.StatusNotFound)
-	s := httptest.NewServer(&status)
-	defer s.Close()
-}
diff --git a/src/cmd/oldlink/internal/ld/testdata/issue10978/main.go b/src/cmd/oldlink/internal/ld/testdata/issue10978/main.go
deleted file mode 100644
index 5e8c097..0000000
--- a/src/cmd/oldlink/internal/ld/testdata/issue10978/main.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 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 undefined()
-
-func defined1() int {
-	// To check multiple errors for a single symbol,
-	// reference undefined more than once.
-	undefined()
-	undefined()
-	return 0
-}
-
-func defined2() {
-	undefined()
-	undefined()
-}
-
-func init() {
-	_ = defined1()
-	defined2()
-}
-
-// The "main" function remains undeclared.
diff --git a/src/cmd/oldlink/internal/ld/testdata/issue10978/main.s b/src/cmd/oldlink/internal/ld/testdata/issue10978/main.s
deleted file mode 100644
index 1d00e76..0000000
--- a/src/cmd/oldlink/internal/ld/testdata/issue10978/main.s
+++ /dev/null
@@ -1 +0,0 @@
-// This file is needed to make "go build" work for package with external functions.
diff --git a/src/cmd/oldlink/internal/ld/testdata/issue25459/a/a.go b/src/cmd/oldlink/internal/ld/testdata/issue25459/a/a.go
deleted file mode 100644
index 6032d76..0000000
--- a/src/cmd/oldlink/internal/ld/testdata/issue25459/a/a.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package a
-
-const Always = true
-
-var Count int
-
-type FuncReturningInt func() int
-
-var PointerToConstIf FuncReturningInt
-
-func ConstIf() int {
-	if Always {
-		return 1
-	}
-	var imdead [4]int
-	imdead[Count] = 1
-	return imdead[0]
-}
-
-func CallConstIf() int {
-	Count += 3
-	return ConstIf()
-}
-
-func Another() {
-	defer func() { PointerToConstIf = ConstIf; Count += 1 }()
-}
diff --git a/src/cmd/oldlink/internal/ld/testdata/issue25459/main/main.go b/src/cmd/oldlink/internal/ld/testdata/issue25459/main/main.go
deleted file mode 100644
index 3f5f365..0000000
--- a/src/cmd/oldlink/internal/ld/testdata/issue25459/main/main.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package main
-
-import "cmd/oldlink/internal/ld/testdata/issue25459/a"
-
-var Glob int
-
-func main() {
-	a.Another()
-	Glob += a.ConstIf() + a.CallConstIf()
-}
diff --git a/src/cmd/oldlink/internal/ld/testdata/issue26237/b.dir/b.go b/src/cmd/oldlink/internal/ld/testdata/issue26237/b.dir/b.go
deleted file mode 100644
index ca57749..0000000
--- a/src/cmd/oldlink/internal/ld/testdata/issue26237/b.dir/b.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package b
-
-var q int
-
-func Top(x int) int {
-	q += 1
-	if q != x {
-		return 3
-	}
-	return 4
-}
-
-func OOO(x int) int {
-	defer func() { q += x & 7 }()
-	return Top(x + 1)
-}
diff --git a/src/cmd/oldlink/internal/ld/testdata/issue26237/main/main.go b/src/cmd/oldlink/internal/ld/testdata/issue26237/main/main.go
deleted file mode 100644
index 88b54f1..0000000
--- a/src/cmd/oldlink/internal/ld/testdata/issue26237/main/main.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package main
-
-import (
-	"fmt"
-
-	b "cmd/oldlink/internal/ld/testdata/issue26237/b.dir"
-)
-
-var skyx int
-
-func main() {
-	skyx += b.OOO(skyx)
-	if b.Top(1) == 99 {
-		fmt.Printf("Beware the Jabberwock, my son!\n")
-	}
-}
diff --git a/src/cmd/oldlink/internal/ld/testdata/issue32233/lib/ObjC.m b/src/cmd/oldlink/internal/ld/testdata/issue32233/lib/ObjC.m
deleted file mode 100644
index 9462788..0000000
--- a/src/cmd/oldlink/internal/ld/testdata/issue32233/lib/ObjC.m
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2019 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.
-
-#import <Foundation/Foundation.h>
-#import <AppKit/NSAppearance.h>
-
-BOOL function(void) {
-#if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && (MAC_OS_X_VERSION_MIN_REQUIRED > 101300)
-  NSAppearance *darkAppearance;
-  if (@available(macOS 10.14, *)) {
-    darkAppearance = [NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
-  }
-#endif
-  return NO;
-}
diff --git a/src/cmd/oldlink/internal/ld/testdata/issue32233/lib/lib.go b/src/cmd/oldlink/internal/ld/testdata/issue32233/lib/lib.go
deleted file mode 100644
index 514b9b9..0000000
--- a/src/cmd/oldlink/internal/ld/testdata/issue32233/lib/lib.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2019 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 lib
-
-/*
-#cgo darwin CFLAGS: -D__MAC_OS_X_VERSION_MAX_ALLOWED=101450
-#cgo darwin LDFLAGS: -framework Foundation -framework AppKit
-#include "stdlib.h"
-int function(void);
-*/
-import "C"
-import "fmt"
-
-func DoC() {
-	C.function()
-	fmt.Println("called c function")
-}
diff --git a/src/cmd/oldlink/internal/ld/testdata/issue32233/main/main.go b/src/cmd/oldlink/internal/ld/testdata/issue32233/main/main.go
deleted file mode 100644
index 9eec6cc..0000000
--- a/src/cmd/oldlink/internal/ld/testdata/issue32233/main/main.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2019 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 "cmd/oldlink/internal/ld/testdata/issue32233/lib"
-
-func main() {
-	lib.DoC()
-}
diff --git a/src/cmd/oldlink/internal/ld/typelink.go b/src/cmd/oldlink/internal/ld/typelink.go
deleted file mode 100644
index 07d04bb..0000000
--- a/src/cmd/oldlink/internal/ld/typelink.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ld
-
-import (
-	"cmd/internal/objabi"
-	"cmd/oldlink/internal/sym"
-	"sort"
-)
-
-type byTypeStr []typelinkSortKey
-
-type typelinkSortKey struct {
-	TypeStr string
-	Type    *sym.Symbol
-}
-
-func (s byTypeStr) Less(i, j int) bool { return s[i].TypeStr < s[j].TypeStr }
-func (s byTypeStr) Len() int           { return len(s) }
-func (s byTypeStr) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-
-// typelink generates the typelink table which is used by reflect.typelinks().
-// Types that should be added to the typelinks table are marked with the
-// MakeTypelink attribute by the compiler.
-func (ctxt *Link) typelink() {
-	typelinks := byTypeStr{}
-	for _, s := range ctxt.Syms.Allsym {
-		if s.Attr.Reachable() && s.Attr.MakeTypelink() {
-			typelinks = append(typelinks, typelinkSortKey{decodetypeStr(ctxt.Arch, s), s})
-		}
-	}
-	sort.Sort(typelinks)
-
-	tl := ctxt.Syms.Lookup("runtime.typelink", 0)
-	tl.Type = sym.STYPELINK
-	tl.Attr |= sym.AttrReachable | sym.AttrLocal
-	tl.Size = int64(4 * len(typelinks))
-	tl.P = make([]byte, tl.Size)
-	tl.R = make([]sym.Reloc, len(typelinks))
-	for i, s := range typelinks {
-		r := &tl.R[i]
-		r.Sym = s.Type
-		r.Off = int32(i * 4)
-		r.Siz = 4
-		r.Type = objabi.R_ADDROFF
-	}
-}
diff --git a/src/cmd/oldlink/internal/ld/util.go b/src/cmd/oldlink/internal/ld/util.go
deleted file mode 100644
index 97c9a44..0000000
--- a/src/cmd/oldlink/internal/ld/util.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ld
-
-import (
-	"cmd/oldlink/internal/sym"
-	"encoding/binary"
-	"fmt"
-	"os"
-)
-
-var atExitFuncs []func()
-
-func AtExit(f func()) {
-	atExitFuncs = append(atExitFuncs, f)
-}
-
-// runAtExitFuncs runs the queued set of AtExit functions.
-func runAtExitFuncs() {
-	for i := len(atExitFuncs) - 1; i >= 0; i-- {
-		atExitFuncs[i]()
-	}
-	atExitFuncs = nil
-}
-
-// Exit exits with code after executing all atExitFuncs.
-func Exit(code int) {
-	runAtExitFuncs()
-	os.Exit(code)
-}
-
-// Exitf logs an error message then calls Exit(2).
-func Exitf(format string, a ...interface{}) {
-	fmt.Fprintf(os.Stderr, os.Args[0]+": "+format+"\n", a...)
-	nerrors++
-	Exit(2)
-}
-
-// Errorf logs an error message.
-//
-// If more than 20 errors have been printed, exit with an error.
-//
-// Logging an error means that on exit cmd/link will delete any
-// output file and return a non-zero error code.
-func Errorf(s *sym.Symbol, format string, args ...interface{}) {
-	if s != nil {
-		format = s.Name + ": " + format
-	}
-	format += "\n"
-	fmt.Fprintf(os.Stderr, format, args...)
-	nerrors++
-	if *flagH {
-		panic("error")
-	}
-	if nerrors > 20 {
-		Exitf("too many errors")
-	}
-}
-
-func artrim(x []byte) string {
-	i := 0
-	j := len(x)
-	for i < len(x) && x[i] == ' ' {
-		i++
-	}
-	for j > i && x[j-1] == ' ' {
-		j--
-	}
-	return string(x[i:j])
-}
-
-func stringtouint32(x []uint32, s string) {
-	for i := 0; len(s) > 0; i++ {
-		var buf [4]byte
-		s = s[copy(buf[:], s):]
-		x[i] = binary.LittleEndian.Uint32(buf[:])
-	}
-}
-
-// contains reports whether v is in s.
-func contains(s []string, v string) bool {
-	for _, x := range s {
-		if x == v {
-			return true
-		}
-	}
-	return false
-}
-
-// implements sort.Interface, for sorting symbols by name.
-type byName []*sym.Symbol
-
-func (s byName) Len() int           { return len(s) }
-func (s byName) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-func (s byName) Less(i, j int) bool { return s[i].Name < s[j].Name }
diff --git a/src/cmd/oldlink/internal/ld/xcoff.go b/src/cmd/oldlink/internal/ld/xcoff.go
deleted file mode 100644
index 4d66d6d..0000000
--- a/src/cmd/oldlink/internal/ld/xcoff.go
+++ /dev/null
@@ -1,1685 +0,0 @@
-// Copyright 2018 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 ld
-
-import (
-	"bytes"
-	"cmd/internal/objabi"
-	"cmd/oldlink/internal/sym"
-	"encoding/binary"
-	"io/ioutil"
-	"math/bits"
-	"path/filepath"
-	"sort"
-	"strings"
-)
-
-// This file handles all algorithms related to XCOFF files generation.
-// Most of them are adaptations of the ones in  cmd/oldlink/internal/pe.go
-// as PE and XCOFF are based on COFF files.
-// XCOFF files generated are 64 bits.
-
-const (
-	// Total amount of space to reserve at the start of the file
-	// for File Header, Auxiliary Header, and Section Headers.
-	// May waste some.
-	XCOFFHDRRESERVE       = FILHSZ_64 + AOUTHSZ_EXEC64 + SCNHSZ_64*23
-	XCOFFSECTALIGN  int64 = 32 // base on dump -o
-
-	// XCOFF binaries should normally have all its sections position-independent.
-	// However, this is not yet possible for .text because of some R_ADDR relocations
-	// inside RODATA symbols.
-	// .data and .bss are position-independent so their address start inside a unreachable
-	// segment during execution to force segfault if something is wrong.
-	XCOFFTEXTBASE = 0x100000000 // Start of text address
-	XCOFFDATABASE = 0x200000000 // Start of data address
-)
-
-// File Header
-type XcoffFileHdr64 struct {
-	Fmagic   uint16 // Target machine
-	Fnscns   uint16 // Number of sections
-	Ftimedat int32  // Time and date of file creation
-	Fsymptr  uint64 // Byte offset to symbol table start
-	Fopthdr  uint16 // Number of bytes in optional header
-	Fflags   uint16 // Flags
-	Fnsyms   int32  // Number of entries in symbol table
-}
-
-const (
-	U64_TOCMAGIC = 0767 // AIX 64-bit XCOFF
-)
-
-// Flags that describe the type of the object file.
-const (
-	F_RELFLG    = 0x0001
-	F_EXEC      = 0x0002
-	F_LNNO      = 0x0004
-	F_FDPR_PROF = 0x0010
-	F_FDPR_OPTI = 0x0020
-	F_DSA       = 0x0040
-	F_VARPG     = 0x0100
-	F_DYNLOAD   = 0x1000
-	F_SHROBJ    = 0x2000
-	F_LOADONLY  = 0x4000
-)
-
-// Auxiliary Header
-type XcoffAoutHdr64 struct {
-	Omagic      int16    // Flags - Ignored If Vstamp Is 1
-	Ovstamp     int16    // Version
-	Odebugger   uint32   // Reserved For Debugger
-	Otextstart  uint64   // Virtual Address Of Text
-	Odatastart  uint64   // Virtual Address Of Data
-	Otoc        uint64   // Toc Address
-	Osnentry    int16    // Section Number For Entry Point
-	Osntext     int16    // Section Number For Text
-	Osndata     int16    // Section Number For Data
-	Osntoc      int16    // Section Number For Toc
-	Osnloader   int16    // Section Number For Loader
-	Osnbss      int16    // Section Number For Bss
-	Oalgntext   int16    // Max Text Alignment
-	Oalgndata   int16    // Max Data Alignment
-	Omodtype    [2]byte  // Module Type Field
-	Ocpuflag    uint8    // Bit Flags - Cputypes Of Objects
-	Ocputype    uint8    // Reserved for CPU type
-	Otextpsize  uint8    // Requested text page size
-	Odatapsize  uint8    // Requested data page size
-	Ostackpsize uint8    // Requested stack page size
-	Oflags      uint8    // Flags And TLS Alignment
-	Otsize      uint64   // Text Size In Bytes
-	Odsize      uint64   // Data Size In Bytes
-	Obsize      uint64   // Bss Size In Bytes
-	Oentry      uint64   // Entry Point Address
-	Omaxstack   uint64   // Max Stack Size Allowed
-	Omaxdata    uint64   // Max Data Size Allowed
-	Osntdata    int16    // Section Number For Tdata Section
-	Osntbss     int16    // Section Number For Tbss Section
-	Ox64flags   uint16   // Additional Flags For 64-Bit Objects
-	Oresv3a     int16    // Reserved
-	Oresv3      [2]int32 // Reserved
-}
-
-// Section Header
-type XcoffScnHdr64 struct {
-	Sname    [8]byte // Section Name
-	Spaddr   uint64  // Physical Address
-	Svaddr   uint64  // Virtual Address
-	Ssize    uint64  // Section Size
-	Sscnptr  uint64  // File Offset To Raw Data
-	Srelptr  uint64  // File Offset To Relocation
-	Slnnoptr uint64  // File Offset To Line Numbers
-	Snreloc  uint32  // Number Of Relocation Entries
-	Snlnno   uint32  // Number Of Line Number Entries
-	Sflags   uint32  // flags
-}
-
-// Flags defining the section type.
-const (
-	STYP_DWARF  = 0x0010
-	STYP_TEXT   = 0x0020
-	STYP_DATA   = 0x0040
-	STYP_BSS    = 0x0080
-	STYP_EXCEPT = 0x0100
-	STYP_INFO   = 0x0200
-	STYP_TDATA  = 0x0400
-	STYP_TBSS   = 0x0800
-	STYP_LOADER = 0x1000
-	STYP_DEBUG  = 0x2000
-	STYP_TYPCHK = 0x4000
-	STYP_OVRFLO = 0x8000
-)
-const (
-	SSUBTYP_DWINFO  = 0x10000 // DWARF info section
-	SSUBTYP_DWLINE  = 0x20000 // DWARF line-number section
-	SSUBTYP_DWPBNMS = 0x30000 // DWARF public names section
-	SSUBTYP_DWPBTYP = 0x40000 // DWARF public types section
-	SSUBTYP_DWARNGE = 0x50000 // DWARF aranges section
-	SSUBTYP_DWABREV = 0x60000 // DWARF abbreviation section
-	SSUBTYP_DWSTR   = 0x70000 // DWARF strings section
-	SSUBTYP_DWRNGES = 0x80000 // DWARF ranges section
-	SSUBTYP_DWLOC   = 0x90000 // DWARF location lists section
-	SSUBTYP_DWFRAME = 0xA0000 // DWARF frames section
-	SSUBTYP_DWMAC   = 0xB0000 // DWARF macros section
-)
-
-// Headers size
-const (
-	FILHSZ_32      = 20
-	FILHSZ_64      = 24
-	AOUTHSZ_EXEC32 = 72
-	AOUTHSZ_EXEC64 = 120
-	SCNHSZ_32      = 40
-	SCNHSZ_64      = 72
-	LDHDRSZ_32     = 32
-	LDHDRSZ_64     = 56
-	LDSYMSZ_64     = 24
-	RELSZ_64       = 14
-)
-
-// Type representing all XCOFF symbols.
-type xcoffSym interface {
-}
-
-// Symbol Table Entry
-type XcoffSymEnt64 struct {
-	Nvalue  uint64 // Symbol value
-	Noffset uint32 // Offset of the name in string table or .debug section
-	Nscnum  int16  // Section number of symbol
-	Ntype   uint16 // Basic and derived type specification
-	Nsclass uint8  // Storage class of symbol
-	Nnumaux int8   // Number of auxiliary entries
-}
-
-const SYMESZ = 18
-
-const (
-	// Nscnum
-	N_DEBUG = -2
-	N_ABS   = -1
-	N_UNDEF = 0
-
-	//Ntype
-	SYM_V_INTERNAL  = 0x1000
-	SYM_V_HIDDEN    = 0x2000
-	SYM_V_PROTECTED = 0x3000
-	SYM_V_EXPORTED  = 0x4000
-	SYM_TYPE_FUNC   = 0x0020 // is function
-)
-
-// Storage Class.
-const (
-	C_NULL    = 0   // Symbol table entry marked for deletion
-	C_EXT     = 2   // External symbol
-	C_STAT    = 3   // Static symbol
-	C_BLOCK   = 100 // Beginning or end of inner block
-	C_FCN     = 101 // Beginning or end of function
-	C_FILE    = 103 // Source file name and compiler information
-	C_HIDEXT  = 107 // Unnamed external symbol
-	C_BINCL   = 108 // Beginning of include file
-	C_EINCL   = 109 // End of include file
-	C_WEAKEXT = 111 // Weak external symbol
-	C_DWARF   = 112 // DWARF symbol
-	C_GSYM    = 128 // Global variable
-	C_LSYM    = 129 // Automatic variable allocated on stack
-	C_PSYM    = 130 // Argument to subroutine allocated on stack
-	C_RSYM    = 131 // Register variable
-	C_RPSYM   = 132 // Argument to function or procedure stored in register
-	C_STSYM   = 133 // Statically allocated symbol
-	C_BCOMM   = 135 // Beginning of common block
-	C_ECOML   = 136 // Local member of common block
-	C_ECOMM   = 137 // End of common block
-	C_DECL    = 140 // Declaration of object
-	C_ENTRY   = 141 // Alternate entry
-	C_FUN     = 142 // Function or procedure
-	C_BSTAT   = 143 // Beginning of static block
-	C_ESTAT   = 144 // End of static block
-	C_GTLS    = 145 // Global thread-local variable
-	C_STTLS   = 146 // Static thread-local variable
-)
-
-// File Auxiliary Entry
-type XcoffAuxFile64 struct {
-	Xzeroes  uint32 // The name is always in the string table
-	Xoffset  uint32 // Offset in the string table
-	X_pad1   [6]byte
-	Xftype   uint8 // Source file string type
-	X_pad2   [2]byte
-	Xauxtype uint8 // Type of auxiliary entry
-}
-
-// Function Auxiliary Entry
-type XcoffAuxFcn64 struct {
-	Xlnnoptr uint64 // File pointer to line number
-	Xfsize   uint32 // Size of function in bytes
-	Xendndx  uint32 // Symbol table index of next entry
-	Xpad     uint8  // Unused
-	Xauxtype uint8  // Type of auxiliary entry
-}
-
-// csect Auxiliary Entry.
-type XcoffAuxCSect64 struct {
-	Xscnlenlo uint32 // Lower 4 bytes of length or symbol table index
-	Xparmhash uint32 // Offset of parameter type-check string
-	Xsnhash   uint16 // .typchk section number
-	Xsmtyp    uint8  // Symbol alignment and type
-	Xsmclas   uint8  // Storage-mapping class
-	Xscnlenhi uint32 // Upper 4 bytes of length or symbol table index
-	Xpad      uint8  // Unused
-	Xauxtype  uint8  // Type of auxiliary entry
-}
-
-// DWARF Auxiliary Entry
-type XcoffAuxDWARF64 struct {
-	Xscnlen  uint64 // Length of this symbol section
-	X_pad    [9]byte
-	Xauxtype uint8 // Type of auxiliary entry
-}
-
-// Auxiliary type
-const (
-	_AUX_EXCEPT = 255
-	_AUX_FCN    = 254
-	_AUX_SYM    = 253
-	_AUX_FILE   = 252
-	_AUX_CSECT  = 251
-	_AUX_SECT   = 250
-)
-
-// Xftype field
-const (
-	XFT_FN = 0   // Source File Name
-	XFT_CT = 1   // Compile Time Stamp
-	XFT_CV = 2   // Compiler Version Number
-	XFT_CD = 128 // Compiler Defined Information/
-
-)
-
-// Symbol type field.
-const (
-	XTY_ER  = 0    // External reference
-	XTY_SD  = 1    // Section definition
-	XTY_LD  = 2    // Label definition
-	XTY_CM  = 3    // Common csect definition
-	XTY_WK  = 0x8  // Weak symbol
-	XTY_EXP = 0x10 // Exported symbol
-	XTY_ENT = 0x20 // Entry point symbol
-	XTY_IMP = 0x40 // Imported symbol
-)
-
-// Storage-mapping class.
-const (
-	XMC_PR     = 0  // Program code
-	XMC_RO     = 1  // Read-only constant
-	XMC_DB     = 2  // Debug dictionary table
-	XMC_TC     = 3  // TOC entry
-	XMC_UA     = 4  // Unclassified
-	XMC_RW     = 5  // Read/Write data
-	XMC_GL     = 6  // Global linkage
-	XMC_XO     = 7  // Extended operation
-	XMC_SV     = 8  // 32-bit supervisor call descriptor
-	XMC_BS     = 9  // BSS class
-	XMC_DS     = 10 // Function descriptor
-	XMC_UC     = 11 // Unnamed FORTRAN common
-	XMC_TC0    = 15 // TOC anchor
-	XMC_TD     = 16 // Scalar data entry in the TOC
-	XMC_SV64   = 17 // 64-bit supervisor call descriptor
-	XMC_SV3264 = 18 // Supervisor call descriptor for both 32-bit and 64-bit
-	XMC_TL     = 20 // Read/Write thread-local data
-	XMC_UL     = 21 // Read/Write thread-local data (.tbss)
-	XMC_TE     = 22 // TOC entry
-)
-
-// Loader Header
-type XcoffLdHdr64 struct {
-	Lversion int32  // Loader section version number
-	Lnsyms   int32  // Number of symbol table entries
-	Lnreloc  int32  // Number of relocation table entries
-	Listlen  uint32 // Length of import file ID string table
-	Lnimpid  int32  // Number of import file IDs
-	Lstlen   uint32 // Length of string table
-	Limpoff  uint64 // Offset to start of import file IDs
-	Lstoff   uint64 // Offset to start of string table
-	Lsymoff  uint64 // Offset to start of symbol table
-	Lrldoff  uint64 // Offset to start of relocation entries
-}
-
-// Loader Symbol
-type XcoffLdSym64 struct {
-	Lvalue  uint64 // Address field
-	Loffset uint32 // Byte offset into string table of symbol name
-	Lscnum  int16  // Section number containing symbol
-	Lsmtype int8   // Symbol type, export, import flags
-	Lsmclas int8   // Symbol storage class
-	Lifile  int32  // Import file ID; ordinal of import file IDs
-	Lparm   uint32 // Parameter type-check field
-}
-
-type xcoffLoaderSymbol struct {
-	sym    *sym.Symbol
-	smtype int8
-	smclas int8
-}
-
-type XcoffLdImportFile64 struct {
-	Limpidpath string
-	Limpidbase string
-	Limpidmem  string
-}
-
-type XcoffLdRel64 struct {
-	Lvaddr  uint64 // Address Field
-	Lrtype  uint16 // Relocation Size and Type
-	Lrsecnm int16  // Section Number being relocated
-	Lsymndx int32  // Loader-Section symbol table index
-}
-
-// xcoffLoaderReloc holds information about a relocation made by the loader.
-type xcoffLoaderReloc struct {
-	sym    *sym.Symbol
-	rel    *sym.Reloc
-	rtype  uint16
-	symndx int32
-}
-
-const (
-	XCOFF_R_POS = 0x00 // A(sym) Positive Relocation
-	XCOFF_R_NEG = 0x01 // -A(sym) Negative Relocation
-	XCOFF_R_REL = 0x02 // A(sym-*) Relative to self
-	XCOFF_R_TOC = 0x03 // A(sym-TOC) Relative to TOC
-	XCOFF_R_TRL = 0x12 // A(sym-TOC) TOC Relative indirect load.
-
-	XCOFF_R_TRLA = 0x13 // A(sym-TOC) TOC Rel load address. modifiable inst
-	XCOFF_R_GL   = 0x05 // A(external TOC of sym) Global Linkage
-	XCOFF_R_TCL  = 0x06 // A(local TOC of sym) Local object TOC address
-	XCOFF_R_RL   = 0x0C // A(sym) Pos indirect load. modifiable instruction
-	XCOFF_R_RLA  = 0x0D // A(sym) Pos Load Address. modifiable instruction
-	XCOFF_R_REF  = 0x0F // AL0(sym) Non relocating ref. No garbage collect
-	XCOFF_R_BA   = 0x08 // A(sym) Branch absolute. Cannot modify instruction
-	XCOFF_R_RBA  = 0x18 // A(sym) Branch absolute. modifiable instruction
-	XCOFF_R_BR   = 0x0A // A(sym-*) Branch rel to self. non modifiable
-	XCOFF_R_RBR  = 0x1A // A(sym-*) Branch rel to self. modifiable instr
-
-	XCOFF_R_TLS    = 0x20 // General-dynamic reference to TLS symbol
-	XCOFF_R_TLS_IE = 0x21 // Initial-exec reference to TLS symbol
-	XCOFF_R_TLS_LD = 0x22 // Local-dynamic reference to TLS symbol
-	XCOFF_R_TLS_LE = 0x23 // Local-exec reference to TLS symbol
-	XCOFF_R_TLSM   = 0x24 // Module reference to TLS symbol
-	XCOFF_R_TLSML  = 0x25 // Module reference to local (own) module
-
-	XCOFF_R_TOCU = 0x30 // Relative to TOC - high order bits
-	XCOFF_R_TOCL = 0x31 // Relative to TOC - low order bits
-)
-
-type XcoffLdStr64 struct {
-	size uint16
-	name string
-}
-
-// xcoffFile is used to build XCOFF file.
-type xcoffFile struct {
-	xfhdr           XcoffFileHdr64
-	xahdr           XcoffAoutHdr64
-	sections        []*XcoffScnHdr64
-	sectText        *XcoffScnHdr64
-	sectData        *XcoffScnHdr64
-	sectBss         *XcoffScnHdr64
-	stringTable     xcoffStringTable
-	sectNameToScnum map[string]int16
-	loaderSize      uint64
-	symtabOffset    int64                // offset to the start of symbol table
-	symbolCount     uint32               // number of symbol table records written
-	symtabSym       []xcoffSym           // XCOFF symbols for the symbol table
-	dynLibraries    map[string]int       // Dynamic libraries in .loader section. The integer represents its import file number (- 1)
-	loaderSymbols   []*xcoffLoaderSymbol // symbols inside .loader symbol table
-	loaderReloc     []*xcoffLoaderReloc  // Reloc that must be made inside loader
-}
-
-// Var used by XCOFF Generation algorithms
-var (
-	xfile xcoffFile
-)
-
-// xcoffStringTable is a XCOFF string table.
-type xcoffStringTable struct {
-	strings    []string
-	stringsLen int
-}
-
-// size returns size of string table t.
-func (t *xcoffStringTable) size() int {
-	// string table starts with 4-byte length at the beginning
-	return t.stringsLen + 4
-}
-
-// add adds string str to string table t.
-func (t *xcoffStringTable) add(str string) int {
-	off := t.size()
-	t.strings = append(t.strings, str)
-	t.stringsLen += len(str) + 1 // each string will have 0 appended to it
-	return off
-}
-
-// write writes string table t into the output file.
-func (t *xcoffStringTable) write(out *OutBuf) {
-	out.Write32(uint32(t.size()))
-	for _, s := range t.strings {
-		out.WriteString(s)
-		out.Write8(0)
-	}
-}
-
-// write writes XCOFF section sect into the output file.
-func (sect *XcoffScnHdr64) write(ctxt *Link) {
-	binary.Write(ctxt.Out, binary.BigEndian, sect)
-	ctxt.Out.Write32(0) // Add 4 empty bytes at the end to match alignment
-}
-
-// addSection adds section to the XCOFF file f.
-func (f *xcoffFile) addSection(name string, addr uint64, size uint64, fileoff uint64, flags uint32) *XcoffScnHdr64 {
-	sect := &XcoffScnHdr64{
-		Spaddr:  addr,
-		Svaddr:  addr,
-		Ssize:   size,
-		Sscnptr: fileoff,
-		Sflags:  flags,
-	}
-	copy(sect.Sname[:], name) // copy string to [8]byte
-	f.sections = append(f.sections, sect)
-	f.sectNameToScnum[name] = int16(len(f.sections))
-	return sect
-}
-
-// addDwarfSection adds a dwarf section to the XCOFF file f.
-// This function is similar to addSection, but Dwarf section names
-// must be modified to conventional names and they are various subtypes.
-func (f *xcoffFile) addDwarfSection(s *sym.Section) *XcoffScnHdr64 {
-	newName, subtype := xcoffGetDwarfSubtype(s.Name)
-	return f.addSection(newName, 0, s.Length, s.Seg.Fileoff+s.Vaddr-s.Seg.Vaddr, STYP_DWARF|subtype)
-}
-
-// xcoffGetDwarfSubtype returns the XCOFF name of the DWARF section str
-// and its subtype constant.
-func xcoffGetDwarfSubtype(str string) (string, uint32) {
-	switch str {
-	default:
-		Exitf("unknown DWARF section name for XCOFF: %s", str)
-	case ".debug_abbrev":
-		return ".dwabrev", SSUBTYP_DWABREV
-	case ".debug_info":
-		return ".dwinfo", SSUBTYP_DWINFO
-	case ".debug_frame":
-		return ".dwframe", SSUBTYP_DWFRAME
-	case ".debug_line":
-		return ".dwline", SSUBTYP_DWLINE
-	case ".debug_loc":
-		return ".dwloc", SSUBTYP_DWLOC
-	case ".debug_pubnames":
-		return ".dwpbnms", SSUBTYP_DWPBNMS
-	case ".debug_pubtypes":
-		return ".dwpbtyp", SSUBTYP_DWPBTYP
-	case ".debug_ranges":
-		return ".dwrnges", SSUBTYP_DWRNGES
-	}
-	// never used
-	return "", 0
-}
-
-// getXCOFFscnum returns the XCOFF section number of a Go section.
-func (f *xcoffFile) getXCOFFscnum(sect *sym.Section) int16 {
-	switch sect.Seg {
-	case &Segtext:
-		return f.sectNameToScnum[".text"]
-	case &Segdata:
-		if sect.Name == ".noptrbss" || sect.Name == ".bss" {
-			return f.sectNameToScnum[".bss"]
-		}
-		if sect.Name == ".tbss" {
-			return f.sectNameToScnum[".tbss"]
-		}
-		return f.sectNameToScnum[".data"]
-	case &Segdwarf:
-		name, _ := xcoffGetDwarfSubtype(sect.Name)
-		return f.sectNameToScnum[name]
-	case &Segrelrodata:
-		return f.sectNameToScnum[".data"]
-	}
-	Errorf(nil, "getXCOFFscnum not implemented for section %s", sect.Name)
-	return -1
-}
-
-// Xcoffinit initialised some internal value and setups
-// already known header information
-func Xcoffinit(ctxt *Link) {
-	xfile.dynLibraries = make(map[string]int)
-
-	HEADR = int32(Rnd(XCOFFHDRRESERVE, XCOFFSECTALIGN))
-	if *FlagTextAddr != -1 {
-		Errorf(nil, "-T not available on AIX")
-	}
-	*FlagTextAddr = XCOFFTEXTBASE + int64(HEADR)
-	if *FlagRound != -1 {
-		Errorf(nil, "-R not available on AIX")
-	}
-	*FlagRound = int(XCOFFSECTALIGN)
-
-}
-
-// SYMBOL TABLE
-
-// type records C_FILE information needed for genasmsym in XCOFF.
-type xcoffSymSrcFile struct {
-	name       string
-	file       *XcoffSymEnt64   // Symbol of this C_FILE
-	csectAux   *XcoffAuxCSect64 // Symbol for the current .csect
-	csectSymNb uint64           // Symbol number for the current .csect
-	csectSize  int64
-}
-
-var (
-	currDwscnoff   = make(map[string]uint64) // Needed to create C_DWARF symbols
-	currSymSrcFile xcoffSymSrcFile
-	outerSymSize   = make(map[string]int64)
-)
-
-// xcoffUpdateOuterSize stores the size of outer symbols in order to have it
-// in the symbol table.
-func xcoffUpdateOuterSize(ctxt *Link, size int64, stype sym.SymKind) {
-	if size == 0 {
-		return
-	}
-
-	switch stype {
-	default:
-		Errorf(nil, "unknown XCOFF outer symbol for type %s", stype.String())
-	case sym.SRODATA, sym.SRODATARELRO, sym.SFUNCTAB, sym.SSTRING:
-		// Nothing to do
-	case sym.STYPERELRO:
-		if ctxt.UseRelro() && (ctxt.BuildMode == BuildModeCArchive || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE) {
-			// runtime.types size must be removed, as it's a real symbol.
-			outerSymSize["typerel.*"] = size - ctxt.Syms.ROLookup("runtime.types", 0).Size
-			return
-		}
-		fallthrough
-	case sym.STYPE:
-		if !ctxt.DynlinkingGo() {
-			// runtime.types size must be removed, as it's a real symbol.
-			outerSymSize["type.*"] = size - ctxt.Syms.ROLookup("runtime.types", 0).Size
-		}
-	case sym.SGOSTRING:
-		outerSymSize["go.string.*"] = size
-	case sym.SGOFUNC:
-		if !ctxt.DynlinkingGo() {
-			outerSymSize["go.func.*"] = size
-		}
-	case sym.SGOFUNCRELRO:
-		outerSymSize["go.funcrel.*"] = size
-	case sym.SGCBITS:
-		outerSymSize["runtime.gcbits.*"] = size
-	case sym.SITABLINK:
-		outerSymSize["runtime.itablink"] = size
-
-	}
-
-}
-
-// addSymbol writes a symbol or an auxiliary symbol entry on ctxt.out.
-func (f *xcoffFile) addSymbol(sym xcoffSym) {
-	f.symtabSym = append(f.symtabSym, sym)
-	f.symbolCount++
-}
-
-// xcoffAlign returns the log base 2 of the symbol's alignment.
-func xcoffAlign(x *sym.Symbol, t SymbolType) uint8 {
-	align := x.Align
-	if align == 0 {
-		if t == TextSym {
-			align = int32(Funcalign)
-		} else {
-			align = symalign(x)
-		}
-	}
-	return logBase2(int(align))
-}
-
-// logBase2 returns the log in base 2 of a.
-func logBase2(a int) uint8 {
-	return uint8(bits.Len(uint(a)) - 1)
-}
-
-// Write symbols needed when a new file appeared:
-// - a C_FILE with one auxiliary entry for its name
-// - C_DWARF symbols to provide debug information
-// - a C_HIDEXT which will be a csect containing all of its functions
-// It needs several parameters to create .csect symbols such as its entry point and its section number.
-//
-// Currently, a new file is in fact a new package. It seems to be OK, but it might change
-// in the future.
-func (f *xcoffFile) writeSymbolNewFile(ctxt *Link, name string, firstEntry uint64, extnum int16) {
-	/* C_FILE */
-	s := &XcoffSymEnt64{
-		Noffset: uint32(f.stringTable.add(".file")),
-		Nsclass: C_FILE,
-		Nscnum:  N_DEBUG,
-		Ntype:   0, // Go isn't inside predefined language.
-		Nnumaux: 1,
-	}
-	f.addSymbol(s)
-	currSymSrcFile.file = s
-
-	// Auxiliary entry for file name.
-	auxf := &XcoffAuxFile64{
-		Xoffset:  uint32(f.stringTable.add(name)),
-		Xftype:   XFT_FN,
-		Xauxtype: _AUX_FILE,
-	}
-	f.addSymbol(auxf)
-
-	/* Dwarf */
-	for _, sect := range Segdwarf.Sections {
-		var dwsize uint64
-		if ctxt.LinkMode == LinkInternal {
-			// Find the size of this corresponding package DWARF compilation unit.
-			// This size is set during DWARF generation (see dwarf.go).
-			dwsize = getDwsectCUSize(sect.Name, name)
-			// .debug_abbrev is common to all packages and not found with the previous function
-			if sect.Name == ".debug_abbrev" {
-				s := ctxt.Syms.ROLookup(sect.Name, 0)
-				dwsize = uint64(s.Size)
-
-			}
-		} else {
-			// There is only one .FILE with external linking.
-			dwsize = sect.Length
-		}
-
-		// get XCOFF name
-		name, _ := xcoffGetDwarfSubtype(sect.Name)
-		s := &XcoffSymEnt64{
-			Nvalue:  currDwscnoff[sect.Name],
-			Noffset: uint32(f.stringTable.add(name)),
-			Nsclass: C_DWARF,
-			Nscnum:  f.getXCOFFscnum(sect),
-			Nnumaux: 1,
-		}
-
-		if currSymSrcFile.csectAux == nil {
-			// Dwarf relocations need the symbol number of .dw* symbols.
-			// It doesn't need to know it for each package, one is enough.
-			// currSymSrcFile.csectAux == nil means first package.
-			dws := ctxt.Syms.Lookup(sect.Name, 0)
-			dws.Dynid = int32(f.symbolCount)
-
-			if sect.Name == ".debug_frame" && ctxt.LinkMode != LinkExternal {
-				// CIE size must be added to the first package.
-				dwsize += 48
-			}
-		}
-
-		f.addSymbol(s)
-
-		// update the DWARF section offset in this file
-		if sect.Name != ".debug_abbrev" {
-			currDwscnoff[sect.Name] += dwsize
-		}
-
-		// Auxiliary dwarf section
-		auxd := &XcoffAuxDWARF64{
-			Xscnlen:  dwsize,
-			Xauxtype: _AUX_SECT,
-		}
-
-		f.addSymbol(auxd)
-	}
-
-	/* .csect */
-	// Check if extnum is in text.
-	// This is temporary and only here to check if this algorithm is correct.
-	if extnum != 1 {
-		Exitf("XCOFF symtab: A new file was detected with its first symbol not in .text")
-	}
-
-	currSymSrcFile.csectSymNb = uint64(f.symbolCount)
-
-	// No offset because no name
-	s = &XcoffSymEnt64{
-		Nvalue:  firstEntry,
-		Nscnum:  extnum,
-		Nsclass: C_HIDEXT,
-		Ntype:   0, // check visibility ?
-		Nnumaux: 1,
-	}
-	f.addSymbol(s)
-
-	aux := &XcoffAuxCSect64{
-		Xsmclas:  XMC_PR,
-		Xsmtyp:   XTY_SD | logBase2(Funcalign)<<3,
-		Xauxtype: _AUX_CSECT,
-	}
-	f.addSymbol(aux)
-
-	currSymSrcFile.csectAux = aux
-	currSymSrcFile.csectSize = 0
-}
-
-// Update values for the previous package.
-//  - Svalue of the C_FILE symbol: if it is the last one, this Svalue must be -1
-//  - Xsclen of the csect symbol.
-func (f *xcoffFile) updatePreviousFile(ctxt *Link, last bool) {
-	// first file
-	if currSymSrcFile.file == nil {
-		return
-	}
-
-	// Update C_FILE
-	cfile := currSymSrcFile.file
-	if last {
-		cfile.Nvalue = 0xFFFFFFFFFFFFFFFF
-	} else {
-		cfile.Nvalue = uint64(f.symbolCount)
-	}
-
-	// update csect scnlen in this auxiliary entry
-	aux := currSymSrcFile.csectAux
-	aux.Xscnlenlo = uint32(currSymSrcFile.csectSize & 0xFFFFFFFF)
-	aux.Xscnlenhi = uint32(currSymSrcFile.csectSize >> 32)
-}
-
-// Write symbol representing a .text function.
-// The symbol table is split with C_FILE corresponding to each package
-// and not to each source file as it should be.
-func (f *xcoffFile) writeSymbolFunc(ctxt *Link, x *sym.Symbol) []xcoffSym {
-	// New XCOFF symbols which will be written.
-	syms := []xcoffSym{}
-
-	// Check if a new file is detected.
-	if strings.Contains(x.Name, "-tramp") || strings.HasPrefix(x.Name, "runtime.text.") {
-		// Trampoline don't have a FILE so there are considered
-		// in the current file.
-		// Same goes for runtime.text.X symbols.
-	} else if x.File == "" { // Undefined global symbol
-		// If this happens, the algorithm must be redone.
-		if currSymSrcFile.name != "" {
-			Exitf("undefined global symbol found inside another file")
-		}
-	} else {
-		// Current file has changed. New C_FILE, C_DWARF, etc must be generated.
-		if currSymSrcFile.name != x.File {
-			if ctxt.LinkMode == LinkInternal {
-				// update previous file values
-				xfile.updatePreviousFile(ctxt, false)
-				currSymSrcFile.name = x.File
-				f.writeSymbolNewFile(ctxt, x.File, uint64(x.Value), xfile.getXCOFFscnum(x.Sect))
-			} else {
-				// With external linking, ld will crash if there is several
-				// .FILE and DWARF debugging enable, somewhere during
-				// the relocation phase.
-				// Therefore, all packages are merged under a fake .FILE
-				// "go_functions".
-				// TODO(aix); remove once ld has been fixed or the triggering
-				// relocation has been found and fixed.
-				if currSymSrcFile.name == "" {
-					currSymSrcFile.name = x.File
-					f.writeSymbolNewFile(ctxt, "go_functions", uint64(x.Value), xfile.getXCOFFscnum(x.Sect))
-				}
-			}
-
-		}
-	}
-
-	s := &XcoffSymEnt64{
-		Nsclass: C_EXT,
-		Noffset: uint32(xfile.stringTable.add(x.Extname())),
-		Nvalue:  uint64(x.Value),
-		Nscnum:  f.getXCOFFscnum(x.Sect),
-		Ntype:   SYM_TYPE_FUNC,
-		Nnumaux: 2,
-	}
-
-	if x.Version != 0 || x.Attr.VisibilityHidden() || x.Attr.Local() {
-		s.Nsclass = C_HIDEXT
-	}
-
-	x.Dynid = int32(xfile.symbolCount)
-	syms = append(syms, s)
-
-	// Update current csect size
-	currSymSrcFile.csectSize += x.Size
-
-	// create auxiliary entries
-	a2 := &XcoffAuxFcn64{
-		Xfsize:   uint32(x.Size),
-		Xlnnoptr: 0,                     // TODO
-		Xendndx:  xfile.symbolCount + 3, // this symbol + 2 aux entries
-		Xauxtype: _AUX_FCN,
-	}
-	syms = append(syms, a2)
-
-	a4 := &XcoffAuxCSect64{
-		Xscnlenlo: uint32(currSymSrcFile.csectSymNb & 0xFFFFFFFF),
-		Xscnlenhi: uint32(currSymSrcFile.csectSymNb >> 32),
-		Xsmclas:   XMC_PR, // Program Code
-		Xsmtyp:    XTY_LD, // label definition (based on C)
-		Xauxtype:  _AUX_CSECT,
-	}
-	a4.Xsmtyp |= uint8(xcoffAlign(x, TextSym) << 3)
-
-	syms = append(syms, a4)
-	return syms
-}
-
-// put function used by genasmsym to write symbol table
-func putaixsym(ctxt *Link, x *sym.Symbol, str string, t SymbolType, addr int64, go_ *sym.Symbol) {
-
-	// All XCOFF symbols generated by this GO symbols
-	// Can be a symbol entry or a auxiliary entry
-	syms := []xcoffSym{}
-
-	switch t {
-	default:
-		return
-
-	case TextSym:
-		if x.FuncInfo != nil || strings.Contains(x.Name, "-tramp") || strings.HasPrefix(x.Name, "runtime.text.") {
-			// Function within a file
-			syms = xfile.writeSymbolFunc(ctxt, x)
-		} else {
-			// Only runtime.text and runtime.etext come through this way
-			if x.Name != "runtime.text" && x.Name != "runtime.etext" && x.Name != "go.buildid" {
-				Exitf("putaixsym: unknown text symbol %s", x.Name)
-			}
-			s := &XcoffSymEnt64{
-				Nsclass: C_HIDEXT,
-				Noffset: uint32(xfile.stringTable.add(str)),
-				Nvalue:  uint64(x.Value),
-				Nscnum:  xfile.getXCOFFscnum(x.Sect),
-				Ntype:   SYM_TYPE_FUNC,
-				Nnumaux: 1,
-			}
-			x.Dynid = int32(xfile.symbolCount)
-			syms = append(syms, s)
-
-			size := uint64(x.Size)
-			a4 := &XcoffAuxCSect64{
-				Xauxtype:  _AUX_CSECT,
-				Xscnlenlo: uint32(size & 0xFFFFFFFF),
-				Xscnlenhi: uint32(size >> 32),
-				Xsmclas:   XMC_PR,
-				Xsmtyp:    XTY_SD,
-			}
-			a4.Xsmtyp |= uint8(xcoffAlign(x, TextSym) << 3)
-			syms = append(syms, a4)
-
-		}
-
-	case DataSym, BSSSym:
-		s := &XcoffSymEnt64{
-			Nsclass: C_EXT,
-			Noffset: uint32(xfile.stringTable.add(str)),
-			Nvalue:  uint64(x.Value),
-			Nscnum:  xfile.getXCOFFscnum(x.Sect),
-			Nnumaux: 1,
-		}
-
-		if x.Version != 0 || x.Attr.VisibilityHidden() || x.Attr.Local() {
-			// There is more symbols in the case of a global data
-			// which are related to the assembly generated
-			// to access such symbols.
-			// But as Golang as its own way to check if a symbol is
-			// global or local (the capital letter), we don't need to
-			// implement them yet.
-			s.Nsclass = C_HIDEXT
-		}
-
-		x.Dynid = int32(xfile.symbolCount)
-		syms = append(syms, s)
-
-		// Create auxiliary entry
-
-		// Normally, size should be the size of csect containing all
-		// the data and bss symbols of one file/package.
-		// However, it's easier to just have a csect for each symbol.
-		// It might change
-		size := uint64(x.Size)
-		a4 := &XcoffAuxCSect64{
-			Xauxtype:  _AUX_CSECT,
-			Xscnlenlo: uint32(size & 0xFFFFFFFF),
-			Xscnlenhi: uint32(size >> 32),
-		}
-
-		if x.Type >= sym.STYPE && x.Type <= sym.SPCLNTAB {
-			if ctxt.LinkMode == LinkExternal && strings.HasPrefix(x.Sect.Name, ".data.rel.ro") {
-				// During external linking, read-only datas with relocation
-				// must be in .data.
-				a4.Xsmclas = XMC_RW
-			} else {
-				// Read only data
-				a4.Xsmclas = XMC_RO
-			}
-		} else if x.Type == sym.SDATA && strings.HasPrefix(x.Name, "TOC.") && ctxt.LinkMode == LinkExternal {
-			a4.Xsmclas = XMC_TC
-		} else if x.Name == "TOC" {
-			a4.Xsmclas = XMC_TC0
-		} else {
-			a4.Xsmclas = XMC_RW
-		}
-		if t == DataSym {
-			a4.Xsmtyp |= XTY_SD
-		} else {
-			a4.Xsmtyp |= XTY_CM
-		}
-
-		a4.Xsmtyp |= uint8(xcoffAlign(x, t) << 3)
-
-		syms = append(syms, a4)
-
-	case UndefinedSym:
-		if x.Type != sym.SDYNIMPORT && x.Type != sym.SHOSTOBJ && x.Type != sym.SUNDEFEXT {
-			return
-		}
-		s := &XcoffSymEnt64{
-			Nsclass: C_EXT,
-			Noffset: uint32(xfile.stringTable.add(str)),
-			Nnumaux: 1,
-		}
-		x.Dynid = int32(xfile.symbolCount)
-		syms = append(syms, s)
-
-		a4 := &XcoffAuxCSect64{
-			Xauxtype: _AUX_CSECT,
-			Xsmclas:  XMC_DS,
-			Xsmtyp:   XTY_ER | XTY_IMP,
-		}
-
-		if x.Name == "__n_pthreads" {
-			// Currently, all imported symbols made by cgo_import_dynamic are
-			// syscall functions, except __n_pthreads which is a variable.
-			// TODO(aix): Find a way to detect variables imported by cgo.
-			a4.Xsmclas = XMC_RW
-		}
-
-		syms = append(syms, a4)
-
-	case TLSSym:
-		s := &XcoffSymEnt64{
-			Nsclass: C_EXT,
-			Noffset: uint32(xfile.stringTable.add(str)),
-			Nscnum:  xfile.getXCOFFscnum(x.Sect),
-			Nvalue:  uint64(x.Value),
-			Nnumaux: 1,
-		}
-
-		x.Dynid = int32(xfile.symbolCount)
-		syms = append(syms, s)
-
-		size := uint64(x.Size)
-		a4 := &XcoffAuxCSect64{
-			Xauxtype:  _AUX_CSECT,
-			Xsmclas:   XMC_UL,
-			Xsmtyp:    XTY_CM,
-			Xscnlenlo: uint32(size & 0xFFFFFFFF),
-			Xscnlenhi: uint32(size >> 32),
-		}
-
-		syms = append(syms, a4)
-	}
-
-	for _, s := range syms {
-		xfile.addSymbol(s)
-	}
-}
-
-// Generate XCOFF Symbol table.
-// It will be written in out file in Asmbxcoff, because it must be
-// at the very end, especially after relocation sections which needs symbols' index.
-func (f *xcoffFile) asmaixsym(ctxt *Link) {
-	// Get correct size for symbols wrapping others symbols like go.string.*
-	// sym.Size can be used directly as the symbols have already been written.
-	for name, size := range outerSymSize {
-		sym := ctxt.Syms.ROLookup(name, 0)
-		if sym == nil {
-			Errorf(nil, "unknown outer symbol with name %s", name)
-		} else {
-			sym.Size = size
-		}
-	}
-
-	genasmsym(ctxt, putaixsym)
-	xfile.updatePreviousFile(ctxt, true)
-}
-
-func (f *xcoffFile) genDynSym(ctxt *Link) {
-	var dynsyms []*sym.Symbol
-	for _, s := range ctxt.Syms.Allsym {
-		if s.Type != sym.SHOSTOBJ && s.Type != sym.SDYNIMPORT {
-			continue
-		}
-		dynsyms = append(dynsyms, s)
-	}
-
-	for _, s := range dynsyms {
-		f.adddynimpsym(ctxt, s)
-
-		if _, ok := f.dynLibraries[s.Dynimplib()]; !ok {
-			f.dynLibraries[s.Dynimplib()] = len(f.dynLibraries)
-		}
-
-	}
-
-}
-
-// (*xcoffFile)adddynimpsym adds the dynamic symbol "s" to a XCOFF file.
-// A new symbol named s.Extname() is created to be the actual dynamic symbol
-// in the .loader section and in the symbol table as an External Reference.
-// The symbol "s" is transformed to SXCOFFTOC to end up in .data section.
-// However, there is no writing protection on those symbols and
-// it might need to be added.
-// TODO(aix): Handles dynamic symbols without library.
-func (f *xcoffFile) adddynimpsym(ctxt *Link, s *sym.Symbol) {
-	// Check that library name is given.
-	// Pattern is already checked when compiling.
-	if ctxt.LinkMode == LinkInternal && s.Dynimplib() == "" {
-		Errorf(s, "imported symbol must have a given library")
-	}
-
-	s.Type = sym.SXCOFFTOC
-
-	// Create new dynamic symbol
-	extsym := ctxt.Syms.Lookup(s.Extname(), 0)
-	extsym.Type = sym.SDYNIMPORT
-	extsym.Attr |= sym.AttrReachable
-	extsym.SetDynimplib(s.Dynimplib())
-	extsym.SetExtname(s.Extname())
-	extsym.SetDynimpvers(s.Dynimpvers())
-
-	// Add loader symbol
-	lds := &xcoffLoaderSymbol{
-		sym:    extsym,
-		smtype: XTY_IMP,
-		smclas: XMC_DS,
-	}
-	if s.Name == "__n_pthreads" {
-		// Currently, all imported symbols made by cgo_import_dynamic are
-		// syscall functions, except __n_pthreads which is a variable.
-		// TODO(aix): Find a way to detect variables imported by cgo.
-		lds.smclas = XMC_RW
-	}
-	f.loaderSymbols = append(f.loaderSymbols, lds)
-
-	// Relocation to retrieve the external address
-	s.AddBytes(make([]byte, 8))
-	s.SetAddr(ctxt.Arch, 0, extsym)
-
-}
-
-// Xcoffadddynrel adds a dynamic relocation in a XCOFF file.
-// This relocation will be made by the loader.
-func Xcoffadddynrel(ctxt *Link, s *sym.Symbol, r *sym.Reloc) bool {
-	if ctxt.LinkMode == LinkExternal {
-		return true
-	}
-	if s.Type <= sym.SPCLNTAB {
-		Errorf(s, "cannot have a relocation to %s in a text section symbol", r.Sym.Name)
-		return false
-	}
-
-	ldr := &xcoffLoaderReloc{
-		sym: s,
-		rel: r,
-	}
-
-	switch r.Type {
-	default:
-		Errorf(s, "unexpected .loader relocation to symbol: %s (type: %s)", r.Sym.Name, r.Type.String())
-		return false
-	case objabi.R_ADDR:
-		if s.Type == sym.SXCOFFTOC && r.Sym.Type == sym.SDYNIMPORT {
-			// Imported symbol relocation
-			for i, dynsym := range xfile.loaderSymbols {
-				if dynsym.sym.Name == r.Sym.Name {
-					ldr.symndx = int32(i + 3) // +3 because of 3 section symbols
-					break
-				}
-			}
-		} else if s.Type == sym.SDATA {
-			switch r.Sym.Sect.Seg {
-			default:
-				Errorf(s, "unknown segment for .loader relocation with symbol %s", r.Sym.Name)
-			case &Segtext:
-			case &Segrodata:
-				ldr.symndx = 0 // .text
-			case &Segdata:
-				if r.Sym.Type == sym.SBSS || r.Sym.Type == sym.SNOPTRBSS {
-					ldr.symndx = 2 // .bss
-				} else {
-					ldr.symndx = 1 // .data
-				}
-
-			}
-
-		} else {
-			Errorf(s, "unexpected type for .loader relocation R_ADDR for symbol %s: %s to %s", r.Sym.Name, s.Type, r.Sym.Type)
-			return false
-		}
-
-		ldr.rtype = 0x3F<<8 + XCOFF_R_POS
-	}
-
-	xfile.loaderReloc = append(xfile.loaderReloc, ldr)
-	return true
-}
-
-func (ctxt *Link) doxcoff() {
-	if *FlagD {
-		// All XCOFF files have dynamic symbols because of the syscalls.
-		Exitf("-d is not available on AIX")
-	}
-
-	// TOC
-	toc := ctxt.Syms.Lookup("TOC", 0)
-	toc.Type = sym.SXCOFFTOC
-	toc.Attr |= sym.AttrReachable
-	toc.Attr |= sym.AttrVisibilityHidden
-
-	// Add entry point to .loader symbols.
-	ep := ctxt.Syms.ROLookup(*flagEntrySymbol, 0)
-	if !ep.Attr.Reachable() {
-		Exitf("wrong entry point")
-	}
-
-	xfile.loaderSymbols = append(xfile.loaderSymbols, &xcoffLoaderSymbol{
-		sym:    ep,
-		smtype: XTY_ENT | XTY_SD,
-		smclas: XMC_DS,
-	})
-
-	xfile.genDynSym(ctxt)
-
-	for _, s := range ctxt.Syms.Allsym {
-		if strings.HasPrefix(s.Name, "TOC.") {
-			s.Type = sym.SXCOFFTOC
-		}
-	}
-
-	if ctxt.LinkMode == LinkExternal {
-		// Change rt0_go name to match name in runtime/cgo:main().
-		rt0 := ctxt.Syms.ROLookup("runtime.rt0_go", 0)
-		ctxt.Syms.Rename(rt0.Name, "runtime_rt0_go", 0, ctxt.Reachparent)
-
-		for _, s := range ctxt.Syms.Allsym {
-			if !s.Attr.CgoExport() {
-				continue
-			}
-
-			name := s.Extname()
-			if s.Type == sym.STEXT {
-				// On AIX, a exported function must have two symbols:
-				// - a .text symbol which must start with a ".".
-				// - a .data symbol which is a function descriptor.
-				ctxt.Syms.Rename(s.Name, "."+name, 0, ctxt.Reachparent)
-
-				desc := ctxt.Syms.Lookup(name, 0)
-				desc.Type = sym.SNOPTRDATA
-				desc.AddAddr(ctxt.Arch, s)
-				desc.AddAddr(ctxt.Arch, toc)
-				desc.AddUint64(ctxt.Arch, 0)
-			}
-		}
-	}
-}
-
-// Loader section
-// Currently, this section is created from scratch when assembling the XCOFF file
-// according to information retrieved in xfile object.
-
-// Create loader section and returns its size
-func Loaderblk(ctxt *Link, off uint64) {
-	xfile.writeLdrScn(ctxt, off)
-}
-
-func (f *xcoffFile) writeLdrScn(ctxt *Link, globalOff uint64) {
-	var symtab []*XcoffLdSym64
-	var strtab []*XcoffLdStr64
-	var importtab []*XcoffLdImportFile64
-	var reloctab []*XcoffLdRel64
-	var dynimpreloc []*XcoffLdRel64
-
-	// As the string table is updated in any loader subsection,
-	//  its length must be computed at the same time.
-	stlen := uint32(0)
-
-	// Loader Header
-	hdr := &XcoffLdHdr64{
-		Lversion: 2,
-		Lsymoff:  LDHDRSZ_64,
-	}
-
-	/* Symbol table */
-	for _, s := range f.loaderSymbols {
-		lds := &XcoffLdSym64{
-			Loffset: uint32(stlen + 2),
-			Lsmtype: s.smtype,
-			Lsmclas: s.smclas,
-		}
-		switch s.smtype {
-		default:
-			Errorf(s.sym, "unexpected loader symbol type: 0x%x", s.smtype)
-		case XTY_ENT | XTY_SD:
-			lds.Lvalue = uint64(s.sym.Value)
-			lds.Lscnum = f.getXCOFFscnum(s.sym.Sect)
-		case XTY_IMP:
-			lds.Lifile = int32(f.dynLibraries[s.sym.Dynimplib()] + 1)
-		}
-		ldstr := &XcoffLdStr64{
-			size: uint16(len(s.sym.Name) + 1), // + null terminator
-			name: s.sym.Name,
-		}
-		stlen += uint32(2 + ldstr.size) // 2 = sizeof ldstr.size
-		symtab = append(symtab, lds)
-		strtab = append(strtab, ldstr)
-
-	}
-
-	hdr.Lnsyms = int32(len(symtab))
-	hdr.Lrldoff = hdr.Lsymoff + uint64(24*hdr.Lnsyms) // 24 = sizeof one symbol
-	off := hdr.Lrldoff                                // current offset is the same of reloc offset
-
-	/* Reloc */
-	ep := ctxt.Syms.ROLookup(*flagEntrySymbol, 0)
-	ldr := &XcoffLdRel64{
-		Lvaddr:  uint64(ep.Value),
-		Lrtype:  0x3F00,
-		Lrsecnm: f.getXCOFFscnum(ep.Sect),
-		Lsymndx: 0,
-	}
-	off += 16
-	reloctab = append(reloctab, ldr)
-
-	off += uint64(16 * len(f.loaderReloc))
-	for _, r := range f.loaderReloc {
-		ldr = &XcoffLdRel64{
-			Lvaddr:  uint64(r.sym.Value + int64(r.rel.Off)),
-			Lrtype:  r.rtype,
-			Lsymndx: r.symndx,
-		}
-
-		if r.sym.Sect != nil {
-			ldr.Lrsecnm = f.getXCOFFscnum(r.sym.Sect)
-		}
-
-		reloctab = append(reloctab, ldr)
-	}
-
-	off += uint64(16 * len(dynimpreloc))
-	reloctab = append(reloctab, dynimpreloc...)
-
-	hdr.Lnreloc = int32(len(reloctab))
-	hdr.Limpoff = off
-
-	/* Import */
-	// Default import: /usr/lib:/lib
-	ldimpf := &XcoffLdImportFile64{
-		Limpidpath: "/usr/lib:/lib",
-	}
-	off += uint64(len(ldimpf.Limpidpath) + len(ldimpf.Limpidbase) + len(ldimpf.Limpidmem) + 3) // + null delimiter
-	importtab = append(importtab, ldimpf)
-
-	// The map created by adddynimpsym associates the name to a number
-	// This number represents the librairie index (- 1) in this import files section
-	// Therefore, they must be sorted before being put inside the section
-	libsOrdered := make([]string, len(f.dynLibraries))
-	for key, val := range f.dynLibraries {
-		if libsOrdered[val] != "" {
-			continue
-		}
-		libsOrdered[val] = key
-	}
-
-	for _, lib := range libsOrdered {
-		// lib string is defined as base.a/mem.o or path/base.a/mem.o
-		n := strings.Split(lib, "/")
-		path := ""
-		base := n[len(n)-2]
-		mem := n[len(n)-1]
-		if len(n) > 2 {
-			path = lib[:len(lib)-len(base)-len(mem)-2]
-
-		}
-		ldimpf = &XcoffLdImportFile64{
-			Limpidpath: path,
-			Limpidbase: base,
-			Limpidmem:  mem,
-		}
-		off += uint64(len(ldimpf.Limpidpath) + len(ldimpf.Limpidbase) + len(ldimpf.Limpidmem) + 3) // + null delimiter
-		importtab = append(importtab, ldimpf)
-	}
-
-	hdr.Lnimpid = int32(len(importtab))
-	hdr.Listlen = uint32(off - hdr.Limpoff)
-	hdr.Lstoff = off
-	hdr.Lstlen = stlen
-
-	/* Writing */
-	ctxt.Out.SeekSet(int64(globalOff))
-	binary.Write(ctxt.Out, ctxt.Arch.ByteOrder, hdr)
-
-	for _, s := range symtab {
-		binary.Write(ctxt.Out, ctxt.Arch.ByteOrder, s)
-
-	}
-	for _, r := range reloctab {
-		binary.Write(ctxt.Out, ctxt.Arch.ByteOrder, r)
-	}
-	for _, f := range importtab {
-		ctxt.Out.WriteString(f.Limpidpath)
-		ctxt.Out.Write8(0)
-		ctxt.Out.WriteString(f.Limpidbase)
-		ctxt.Out.Write8(0)
-		ctxt.Out.WriteString(f.Limpidmem)
-		ctxt.Out.Write8(0)
-	}
-	for _, s := range strtab {
-		ctxt.Out.Write16(s.size)
-		ctxt.Out.WriteString(s.name)
-		ctxt.Out.Write8(0) // null terminator
-	}
-
-	f.loaderSize = off + uint64(stlen)
-	ctxt.Out.Flush()
-
-	/* again for printing */
-	if !*flagA {
-		return
-	}
-
-	ctxt.Logf("\n.loader section")
-	// write in buf
-	var buf bytes.Buffer
-
-	binary.Write(&buf, ctxt.Arch.ByteOrder, hdr)
-	for _, s := range symtab {
-		binary.Write(&buf, ctxt.Arch.ByteOrder, s)
-
-	}
-	for _, f := range importtab {
-		buf.WriteString(f.Limpidpath)
-		buf.WriteByte(0)
-		buf.WriteString(f.Limpidbase)
-		buf.WriteByte(0)
-		buf.WriteString(f.Limpidmem)
-		buf.WriteByte(0)
-	}
-	for _, s := range strtab {
-		binary.Write(&buf, ctxt.Arch.ByteOrder, s.size)
-		buf.WriteString(s.name)
-		buf.WriteByte(0) // null terminator
-	}
-
-	// Log buffer
-	ctxt.Logf("\n\t%.8x|", globalOff)
-	for i, b := range buf.Bytes() {
-		if i > 0 && i%16 == 0 {
-			ctxt.Logf("\n\t%.8x|", uint64(globalOff)+uint64(i))
-		}
-		ctxt.Logf(" %.2x", b)
-	}
-	ctxt.Logf("\n")
-
-}
-
-// XCOFF assembling and writing file
-
-func (f *xcoffFile) writeFileHeader(ctxt *Link) {
-	// File header
-	f.xfhdr.Fmagic = U64_TOCMAGIC
-	f.xfhdr.Fnscns = uint16(len(f.sections))
-	f.xfhdr.Ftimedat = 0
-
-	if !*FlagS {
-		f.xfhdr.Fsymptr = uint64(f.symtabOffset)
-		f.xfhdr.Fnsyms = int32(f.symbolCount)
-	}
-
-	if ctxt.BuildMode == BuildModeExe && ctxt.LinkMode == LinkInternal {
-		f.xfhdr.Fopthdr = AOUTHSZ_EXEC64
-		f.xfhdr.Fflags = F_EXEC
-
-		// auxiliary header
-		f.xahdr.Ovstamp = 1 // based on dump -o
-		f.xahdr.Omagic = 0x10b
-		copy(f.xahdr.Omodtype[:], "1L")
-		entry := ctxt.Syms.ROLookup(*flagEntrySymbol, 0)
-		f.xahdr.Oentry = uint64(entry.Value)
-		f.xahdr.Osnentry = f.getXCOFFscnum(entry.Sect)
-		toc := ctxt.Syms.ROLookup("TOC", 0)
-		f.xahdr.Otoc = uint64(toc.Value)
-		f.xahdr.Osntoc = f.getXCOFFscnum(toc.Sect)
-
-		f.xahdr.Oalgntext = int16(logBase2(int(Funcalign)))
-		f.xahdr.Oalgndata = 0x5
-
-		binary.Write(ctxt.Out, binary.BigEndian, &f.xfhdr)
-		binary.Write(ctxt.Out, binary.BigEndian, &f.xahdr)
-	} else {
-		f.xfhdr.Fopthdr = 0
-		binary.Write(ctxt.Out, binary.BigEndian, &f.xfhdr)
-	}
-
-}
-
-func xcoffwrite(ctxt *Link) {
-	ctxt.Out.SeekSet(0)
-
-	xfile.writeFileHeader(ctxt)
-
-	for _, sect := range xfile.sections {
-		sect.write(ctxt)
-	}
-}
-
-// Generate XCOFF assembly file
-func Asmbxcoff(ctxt *Link, fileoff int64) {
-	xfile.sectNameToScnum = make(map[string]int16)
-
-	// Add sections
-	s := xfile.addSection(".text", Segtext.Vaddr, Segtext.Length, Segtext.Fileoff, STYP_TEXT)
-	xfile.xahdr.Otextstart = s.Svaddr
-	xfile.xahdr.Osntext = xfile.sectNameToScnum[".text"]
-	xfile.xahdr.Otsize = s.Ssize
-	xfile.sectText = s
-
-	segdataVaddr := Segdata.Vaddr
-	segdataFilelen := Segdata.Filelen
-	segdataFileoff := Segdata.Fileoff
-	segbssFilelen := Segdata.Length - Segdata.Filelen
-	if len(Segrelrodata.Sections) > 0 {
-		// Merge relro segment to data segment as
-		// relro data are inside data segment on AIX.
-		segdataVaddr = Segrelrodata.Vaddr
-		segdataFileoff = Segrelrodata.Fileoff
-		segdataFilelen = Segdata.Vaddr + Segdata.Filelen - Segrelrodata.Vaddr
-	}
-
-	s = xfile.addSection(".data", segdataVaddr, segdataFilelen, segdataFileoff, STYP_DATA)
-	xfile.xahdr.Odatastart = s.Svaddr
-	xfile.xahdr.Osndata = xfile.sectNameToScnum[".data"]
-	xfile.xahdr.Odsize = s.Ssize
-	xfile.sectData = s
-
-	s = xfile.addSection(".bss", segdataVaddr+segdataFilelen, segbssFilelen, 0, STYP_BSS)
-	xfile.xahdr.Osnbss = xfile.sectNameToScnum[".bss"]
-	xfile.xahdr.Obsize = s.Ssize
-	xfile.sectBss = s
-
-	if ctxt.LinkMode == LinkExternal {
-		var tbss *sym.Section
-		for _, s := range Segdata.Sections {
-			if s.Name == ".tbss" {
-				tbss = s
-				break
-			}
-		}
-		s = xfile.addSection(".tbss", tbss.Vaddr, tbss.Length, 0, STYP_TBSS)
-	}
-
-	// add dwarf sections
-	for _, sect := range Segdwarf.Sections {
-		xfile.addDwarfSection(sect)
-	}
-
-	// add and write remaining sections
-	if ctxt.LinkMode == LinkInternal {
-		// Loader section
-		if ctxt.BuildMode == BuildModeExe {
-			Loaderblk(ctxt, uint64(fileoff))
-			s = xfile.addSection(".loader", 0, xfile.loaderSize, uint64(fileoff), STYP_LOADER)
-			xfile.xahdr.Osnloader = xfile.sectNameToScnum[".loader"]
-
-			// Update fileoff for symbol table
-			fileoff += int64(xfile.loaderSize)
-		}
-	}
-
-	// Create Symbol table
-	xfile.asmaixsym(ctxt)
-
-	if ctxt.LinkMode == LinkExternal {
-		xfile.emitRelocations(ctxt, fileoff)
-	}
-
-	// Write Symbol table
-	xfile.symtabOffset = ctxt.Out.Offset()
-	for _, s := range xfile.symtabSym {
-		binary.Write(ctxt.Out, ctxt.Arch.ByteOrder, s)
-	}
-	// write string table
-	xfile.stringTable.write(ctxt.Out)
-
-	ctxt.Out.Flush()
-
-	// write headers
-	xcoffwrite(ctxt)
-}
-
-// byOffset is used to sort relocations by offset
-type byOffset []sym.Reloc
-
-func (x byOffset) Len() int { return len(x) }
-
-func (x byOffset) Swap(i, j int) {
-	x[i], x[j] = x[j], x[i]
-}
-
-func (x byOffset) Less(i, j int) bool {
-	return x[i].Off < x[j].Off
-}
-
-// emitRelocations emits relocation entries for go.o in external linking.
-func (f *xcoffFile) emitRelocations(ctxt *Link, fileoff int64) {
-	ctxt.Out.SeekSet(fileoff)
-	for ctxt.Out.Offset()&7 != 0 {
-		ctxt.Out.Write8(0)
-	}
-
-	// relocsect relocates symbols from first in section sect, and returns
-	// the total number of relocations emitted.
-	relocsect := func(sect *sym.Section, syms []*sym.Symbol, base uint64) uint32 {
-		// ctxt.Logf("%s 0x%x\n", sect.Name, sect.Vaddr)
-		// If main section has no bits, nothing to relocate.
-		if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
-			return 0
-		}
-		sect.Reloff = uint64(ctxt.Out.Offset())
-		for i, s := range syms {
-			if !s.Attr.Reachable() {
-				continue
-			}
-			if uint64(s.Value) >= sect.Vaddr {
-				syms = syms[i:]
-				break
-			}
-		}
-		eaddr := int64(sect.Vaddr + sect.Length)
-		for _, s := range syms {
-			if !s.Attr.Reachable() {
-				continue
-			}
-			if s.Value >= int64(eaddr) {
-				break
-			}
-
-			// Relocation must be ordered by address, so s.R is ordered by Off.
-			sort.Sort(byOffset(s.R))
-
-			for ri := range s.R {
-
-				r := &s.R[ri]
-
-				if r.Done {
-					continue
-				}
-				if r.Xsym == nil {
-					Errorf(s, "missing xsym in relocation")
-					continue
-				}
-				if r.Xsym.Dynid < 0 {
-					Errorf(s, "reloc %s to non-coff symbol %s (outer=%s) %d %d", r.Type.String(), r.Sym.Name, r.Xsym.Name, r.Sym.Type, r.Xsym.Dynid)
-				}
-				if !thearch.Xcoffreloc1(ctxt.Arch, ctxt.Out, s, r, int64(uint64(s.Value+int64(r.Off))-base)) {
-					Errorf(s, "unsupported obj reloc %d(%s)/%d to %s", r.Type, r.Type.String(), r.Siz, r.Sym.Name)
-				}
-			}
-		}
-		sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
-		return uint32(sect.Rellen) / RELSZ_64
-	}
-	sects := []struct {
-		xcoffSect *XcoffScnHdr64
-		segs      []*sym.Segment
-	}{
-		{f.sectText, []*sym.Segment{&Segtext}},
-		{f.sectData, []*sym.Segment{&Segrelrodata, &Segdata}},
-	}
-	for _, s := range sects {
-		s.xcoffSect.Srelptr = uint64(ctxt.Out.Offset())
-		n := uint32(0)
-		for _, seg := range s.segs {
-			for _, sect := range seg.Sections {
-				if sect.Name == ".text" {
-					n += relocsect(sect, ctxt.Textp, 0)
-				} else {
-					n += relocsect(sect, datap, 0)
-				}
-			}
-		}
-		s.xcoffSect.Snreloc += n
-	}
-
-dwarfLoop:
-	for _, sect := range Segdwarf.Sections {
-		for _, xcoffSect := range f.sections {
-			_, subtyp := xcoffGetDwarfSubtype(sect.Name)
-			if xcoffSect.Sflags&0xF0000 == subtyp {
-				xcoffSect.Srelptr = uint64(ctxt.Out.Offset())
-				xcoffSect.Snreloc = relocsect(sect, dwarfp, sect.Vaddr)
-				continue dwarfLoop
-			}
-		}
-		Errorf(nil, "emitRelocations: could not find %q section", sect.Name)
-	}
-}
-
-// xcoffCreateExportFile creates a file with exported symbols for
-// -Wl,-bE option.
-// ld won't export symbols unless they are listed in an export file.
-func xcoffCreateExportFile(ctxt *Link) (fname string) {
-	fname = filepath.Join(*flagTmpdir, "export_file.exp")
-	var buf bytes.Buffer
-
-	for _, s := range ctxt.Syms.Allsym {
-		if !s.Attr.CgoExport() {
-			continue
-		}
-		if !strings.HasPrefix(s.String(), "_cgoexp_") {
-			continue
-		}
-
-		// Retrieve the name of the initial symbol
-		// exported by cgo.
-		// The corresponding Go symbol is:
-		// _cgoexp_hashcode_symname.
-		name := strings.SplitN(s.Extname(), "_", 4)[3]
-
-		buf.Write([]byte(name + "\n"))
-	}
-
-	err := ioutil.WriteFile(fname, buf.Bytes(), 0666)
-	if err != nil {
-		Errorf(nil, "WriteFile %s failed: %v", fname, err)
-	}
-
-	return fname
-
-}
diff --git a/src/cmd/oldlink/internal/loadelf/ldelf.go b/src/cmd/oldlink/internal/loadelf/ldelf.go
deleted file mode 100644
index db37db9..0000000
--- a/src/cmd/oldlink/internal/loadelf/ldelf.go
+++ /dev/null
@@ -1,1282 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package loadelf implements an ELF file reader.
-package loadelf
-
-import (
-	"bytes"
-	"cmd/internal/bio"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/loader"
-	"cmd/oldlink/internal/sym"
-	"debug/elf"
-	"encoding/binary"
-	"fmt"
-	"io"
-	"log"
-	"sort"
-	"strings"
-)
-
-/*
-Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c
-http://code.swtch.com/plan9port/src/tip/src/libmach/
-
-	Copyright © 2004 Russ Cox.
-	Portions Copyright © 2008-2010 Google Inc.
-	Portions Copyright © 2010 The Go Authors.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-const (
-	ElfClassNone = 0
-	ElfClass32   = 1
-	ElfClass64   = 2
-)
-
-const (
-	ElfDataNone = 0
-	ElfDataLsb  = 1
-	ElfDataMsb  = 2
-)
-
-const (
-	ElfTypeNone         = 0
-	ElfTypeRelocatable  = 1
-	ElfTypeExecutable   = 2
-	ElfTypeSharedObject = 3
-	ElfTypeCore         = 4
-)
-
-const (
-	ElfMachNone        = 0
-	ElfMach32100       = 1
-	ElfMachSparc       = 2
-	ElfMach386         = 3
-	ElfMach68000       = 4
-	ElfMach88000       = 5
-	ElfMach486         = 6
-	ElfMach860         = 7
-	ElfMachMips        = 8
-	ElfMachS370        = 9
-	ElfMachMipsLe      = 10
-	ElfMachParisc      = 15
-	ElfMachVpp500      = 17
-	ElfMachSparc32Plus = 18
-	ElfMach960         = 19
-	ElfMachPower       = 20
-	ElfMachPower64     = 21
-	ElfMachS390        = 22
-	ElfMachV800        = 36
-	ElfMachFr20        = 37
-	ElfMachRh32        = 38
-	ElfMachRce         = 39
-	ElfMachArm         = 40
-	ElfMachAlpha       = 41
-	ElfMachSH          = 42
-	ElfMachSparc9      = 43
-	ElfMachAmd64       = 62
-	ElfMachArm64       = 183
-)
-
-const (
-	ElfAbiNone     = 0
-	ElfAbiSystemV  = 0
-	ElfAbiHPUX     = 1
-	ElfAbiNetBSD   = 2
-	ElfAbiLinux    = 3
-	ElfAbiSolaris  = 6
-	ElfAbiAix      = 7
-	ElfAbiIrix     = 8
-	ElfAbiFreeBSD  = 9
-	ElfAbiTru64    = 10
-	ElfAbiModesto  = 11
-	ElfAbiOpenBSD  = 12
-	ElfAbiARM      = 97
-	ElfAbiEmbedded = 255
-)
-
-const (
-	ElfSectNone      = 0
-	ElfSectProgbits  = 1
-	ElfSectSymtab    = 2
-	ElfSectStrtab    = 3
-	ElfSectRela      = 4
-	ElfSectHash      = 5
-	ElfSectDynamic   = 6
-	ElfSectNote      = 7
-	ElfSectNobits    = 8
-	ElfSectRel       = 9
-	ElfSectShlib     = 10
-	ElfSectDynsym    = 11
-	ElfSectFlagWrite = 0x1
-	ElfSectFlagAlloc = 0x2
-	ElfSectFlagExec  = 0x4
-)
-
-const (
-	ElfSymBindLocal  = 0
-	ElfSymBindGlobal = 1
-	ElfSymBindWeak   = 2
-)
-
-const (
-	ElfSymTypeNone    = 0
-	ElfSymTypeObject  = 1
-	ElfSymTypeFunc    = 2
-	ElfSymTypeSection = 3
-	ElfSymTypeFile    = 4
-	ElfSymTypeCommon  = 5
-	ElfSymTypeTLS     = 6
-)
-
-const (
-	ElfSymShnNone   = 0
-	ElfSymShnAbs    = 0xFFF1
-	ElfSymShnCommon = 0xFFF2
-)
-
-const (
-	ElfProgNone      = 0
-	ElfProgLoad      = 1
-	ElfProgDynamic   = 2
-	ElfProgInterp    = 3
-	ElfProgNote      = 4
-	ElfProgShlib     = 5
-	ElfProgPhdr      = 6
-	ElfProgFlagExec  = 0x1
-	ElfProgFlagWrite = 0x2
-	ElfProgFlagRead  = 0x4
-)
-
-const (
-	ElfNotePrStatus     = 1
-	ElfNotePrFpreg      = 2
-	ElfNotePrPsinfo     = 3
-	ElfNotePrTaskstruct = 4
-	ElfNotePrAuxv       = 6
-	ElfNotePrXfpreg     = 0x46e62b7f
-)
-
-// TODO(crawshaw): de-duplicate with cmd/oldlink/internal/ld/elf.go.
-const (
-	ELF64SYMSIZE = 24
-	ELF32SYMSIZE = 16
-
-	SHT_ARM_ATTRIBUTES = 0x70000003
-)
-
-type ElfHdrBytes struct {
-	Ident     [16]uint8
-	Type      [2]uint8
-	Machine   [2]uint8
-	Version   [4]uint8
-	Entry     [4]uint8
-	Phoff     [4]uint8
-	Shoff     [4]uint8
-	Flags     [4]uint8
-	Ehsize    [2]uint8
-	Phentsize [2]uint8
-	Phnum     [2]uint8
-	Shentsize [2]uint8
-	Shnum     [2]uint8
-	Shstrndx  [2]uint8
-}
-
-type ElfSectBytes struct {
-	Name    [4]uint8
-	Type    [4]uint8
-	Flags   [4]uint8
-	Addr    [4]uint8
-	Off     [4]uint8
-	Size    [4]uint8
-	Link    [4]uint8
-	Info    [4]uint8
-	Align   [4]uint8
-	Entsize [4]uint8
-}
-
-type ElfProgBytes struct {
-}
-
-type ElfSymBytes struct {
-	Name  [4]uint8
-	Value [4]uint8
-	Size  [4]uint8
-	Info  uint8
-	Other uint8
-	Shndx [2]uint8
-}
-
-type ElfHdrBytes64 struct {
-	Ident     [16]uint8
-	Type      [2]uint8
-	Machine   [2]uint8
-	Version   [4]uint8
-	Entry     [8]uint8
-	Phoff     [8]uint8
-	Shoff     [8]uint8
-	Flags     [4]uint8
-	Ehsize    [2]uint8
-	Phentsize [2]uint8
-	Phnum     [2]uint8
-	Shentsize [2]uint8
-	Shnum     [2]uint8
-	Shstrndx  [2]uint8
-}
-
-type ElfSectBytes64 struct {
-	Name    [4]uint8
-	Type    [4]uint8
-	Flags   [8]uint8
-	Addr    [8]uint8
-	Off     [8]uint8
-	Size    [8]uint8
-	Link    [4]uint8
-	Info    [4]uint8
-	Align   [8]uint8
-	Entsize [8]uint8
-}
-
-type ElfProgBytes64 struct {
-}
-
-type ElfSymBytes64 struct {
-	Name  [4]uint8
-	Info  uint8
-	Other uint8
-	Shndx [2]uint8
-	Value [8]uint8
-	Size  [8]uint8
-}
-
-type ElfSect struct {
-	name    string
-	nameoff uint32
-	type_   uint32
-	flags   uint64
-	addr    uint64
-	off     uint64
-	size    uint64
-	link    uint32
-	info    uint32
-	align   uint64
-	entsize uint64
-	base    []byte
-	sym     *sym.Symbol
-}
-
-type ElfObj struct {
-	f         *bio.Reader
-	base      int64 // offset in f where ELF begins
-	length    int64 // length of ELF
-	is64      int
-	name      string
-	e         binary.ByteOrder
-	sect      []ElfSect
-	nsect     uint
-	nsymtab   int
-	symtab    *ElfSect
-	symstr    *ElfSect
-	type_     uint32
-	machine   uint32
-	version   uint32
-	entry     uint64
-	phoff     uint64
-	shoff     uint64
-	flags     uint32
-	ehsize    uint32
-	phentsize uint32
-	phnum     uint32
-	shentsize uint32
-	shnum     uint32
-	shstrndx  uint32
-}
-
-type ElfSym struct {
-	name  string
-	value uint64
-	size  uint64
-	bind  uint8
-	type_ uint8
-	other uint8
-	shndx uint16
-	sym   *sym.Symbol
-}
-
-var ElfMagic = [4]uint8{0x7F, 'E', 'L', 'F'}
-
-const (
-	TagFile               = 1
-	TagCPUName            = 4
-	TagCPURawName         = 5
-	TagCompatibility      = 32
-	TagNoDefaults         = 64
-	TagAlsoCompatibleWith = 65
-	TagABIVFPArgs         = 28
-)
-
-type elfAttribute struct {
-	tag  uint64
-	sval string
-	ival uint64
-}
-
-type elfAttributeList struct {
-	data []byte
-	err  error
-}
-
-func (a *elfAttributeList) string() string {
-	if a.err != nil {
-		return ""
-	}
-	nul := bytes.IndexByte(a.data, 0)
-	if nul < 0 {
-		a.err = io.EOF
-		return ""
-	}
-	s := string(a.data[:nul])
-	a.data = a.data[nul+1:]
-	return s
-}
-
-func (a *elfAttributeList) uleb128() uint64 {
-	if a.err != nil {
-		return 0
-	}
-	v, size := binary.Uvarint(a.data)
-	a.data = a.data[size:]
-	return v
-}
-
-// Read an elfAttribute from the list following the rules used on ARM systems.
-func (a *elfAttributeList) armAttr() elfAttribute {
-	attr := elfAttribute{tag: a.uleb128()}
-	switch {
-	case attr.tag == TagCompatibility:
-		attr.ival = a.uleb128()
-		attr.sval = a.string()
-
-	case attr.tag == 64: // Tag_nodefaults has no argument
-
-	case attr.tag == 65: // Tag_also_compatible_with
-		// Not really, but we don't actually care about this tag.
-		attr.sval = a.string()
-
-	// Tag with string argument
-	case attr.tag == TagCPUName || attr.tag == TagCPURawName || (attr.tag >= 32 && attr.tag&1 != 0):
-		attr.sval = a.string()
-
-	default: // Tag with integer argument
-		attr.ival = a.uleb128()
-	}
-	return attr
-}
-
-func (a *elfAttributeList) done() bool {
-	if a.err != nil || len(a.data) == 0 {
-		return true
-	}
-	return false
-}
-
-// Look for the attribute that indicates the object uses the hard-float ABI (a
-// file-level attribute with tag Tag_VFP_arch and value 1). Unfortunately the
-// format used means that we have to parse all of the file-level attributes to
-// find the one we are looking for. This format is slightly documented in "ELF
-// for the ARM Architecture" but mostly this is derived from reading the source
-// to gold and readelf.
-func parseArmAttributes(e binary.ByteOrder, data []byte) (found bool, ehdrFlags uint32, err error) {
-	found = false
-	if data[0] != 'A' {
-		return false, 0, fmt.Errorf(".ARM.attributes has unexpected format %c\n", data[0])
-	}
-	data = data[1:]
-	for len(data) != 0 {
-		sectionlength := e.Uint32(data)
-		sectiondata := data[4:sectionlength]
-		data = data[sectionlength:]
-
-		nulIndex := bytes.IndexByte(sectiondata, 0)
-		if nulIndex < 0 {
-			return false, 0, fmt.Errorf("corrupt .ARM.attributes (section name not NUL-terminated)\n")
-		}
-		name := string(sectiondata[:nulIndex])
-		sectiondata = sectiondata[nulIndex+1:]
-
-		if name != "aeabi" {
-			continue
-		}
-		for len(sectiondata) != 0 {
-			subsectiontag, sz := binary.Uvarint(sectiondata)
-			subsectionsize := e.Uint32(sectiondata[sz:])
-			subsectiondata := sectiondata[sz+4 : subsectionsize]
-			sectiondata = sectiondata[subsectionsize:]
-
-			if subsectiontag != TagFile {
-				continue
-			}
-			attrList := elfAttributeList{data: subsectiondata}
-			for !attrList.done() {
-				attr := attrList.armAttr()
-				if attr.tag == TagABIVFPArgs && attr.ival == 1 {
-					found = true
-					ehdrFlags = 0x5000402 // has entry point, Version5 EABI, hard-float ABI
-				}
-			}
-			if attrList.err != nil {
-				return false, 0, fmt.Errorf("could not parse .ARM.attributes\n")
-			}
-		}
-	}
-	return found, ehdrFlags, nil
-}
-
-func Load(l *loader.Loader, arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length int64, pn string, flags uint32) ([]*sym.Symbol, uint32, error) {
-	newSym := func(name string, version int) *sym.Symbol {
-		return l.Create(name, syms)
-	}
-	lookup := func(name string, version int) *sym.Symbol {
-		return l.LookupOrCreate(name, version, syms)
-	}
-	return load(arch, syms.IncVersion(), newSym, lookup, f, pkg, length, pn, flags)
-}
-
-func LoadOld(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length int64, pn string, flags uint32) ([]*sym.Symbol, uint32, error) {
-	return load(arch, syms.IncVersion(), syms.Newsym, syms.Lookup, f, pkg, length, pn, flags)
-}
-
-type lookupFunc func(string, int) *sym.Symbol
-
-// load loads the ELF file pn from f.
-// Symbols are written into syms, and a slice of the text symbols is returned.
-//
-// On ARM systems, Load will attempt to determine what ELF header flags to
-// emit by scanning the attributes in the ELF file being loaded. The
-// parameter initEhdrFlags contains the current header flags for the output
-// object, and the returned ehdrFlags contains what this Load function computes.
-// TODO: find a better place for this logic.
-func load(arch *sys.Arch, localSymVersion int, newSym, lookup lookupFunc, f *bio.Reader, pkg string, length int64, pn string, initEhdrFlags uint32) (textp []*sym.Symbol, ehdrFlags uint32, err error) {
-	errorf := func(str string, args ...interface{}) ([]*sym.Symbol, uint32, error) {
-		return nil, 0, fmt.Errorf("loadelf: %s: %v", pn, fmt.Sprintf(str, args...))
-	}
-
-	base := f.Offset()
-
-	var hdrbuf [64]uint8
-	if _, err := io.ReadFull(f, hdrbuf[:]); err != nil {
-		return errorf("malformed elf file: %v", err)
-	}
-	hdr := new(ElfHdrBytes)
-	binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter
-	if string(hdr.Ident[:4]) != "\x7FELF" {
-		return errorf("malformed elf file, bad header")
-	}
-	var e binary.ByteOrder
-	switch hdr.Ident[5] {
-	case ElfDataLsb:
-		e = binary.LittleEndian
-
-	case ElfDataMsb:
-		e = binary.BigEndian
-
-	default:
-		return errorf("malformed elf file, unknown header")
-	}
-
-	// read header
-	elfobj := new(ElfObj)
-
-	elfobj.e = e
-	elfobj.f = f
-	elfobj.base = base
-	elfobj.length = length
-	elfobj.name = pn
-
-	is64 := 0
-	if hdr.Ident[4] == ElfClass64 {
-		is64 = 1
-		hdr := new(ElfHdrBytes64)
-		binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter
-		elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
-		elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
-		elfobj.version = e.Uint32(hdr.Version[:])
-		elfobj.phoff = e.Uint64(hdr.Phoff[:])
-		elfobj.shoff = e.Uint64(hdr.Shoff[:])
-		elfobj.flags = e.Uint32(hdr.Flags[:])
-		elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:]))
-		elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:]))
-		elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:]))
-		elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:]))
-		elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:]))
-		elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:]))
-	} else {
-		elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
-		elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
-		elfobj.version = e.Uint32(hdr.Version[:])
-		elfobj.entry = uint64(e.Uint32(hdr.Entry[:]))
-		elfobj.phoff = uint64(e.Uint32(hdr.Phoff[:]))
-		elfobj.shoff = uint64(e.Uint32(hdr.Shoff[:]))
-		elfobj.flags = e.Uint32(hdr.Flags[:])
-		elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:]))
-		elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:]))
-		elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:]))
-		elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:]))
-		elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:]))
-		elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:]))
-	}
-
-	elfobj.is64 = is64
-
-	if v := uint32(hdr.Ident[6]); v != elfobj.version {
-		return errorf("malformed elf version: got %d, want %d", v, elfobj.version)
-	}
-
-	if e.Uint16(hdr.Type[:]) != ElfTypeRelocatable {
-		return errorf("elf but not elf relocatable object")
-	}
-
-	switch arch.Family {
-	default:
-		return errorf("elf %s unimplemented", arch.Name)
-
-	case sys.MIPS:
-		if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass32 {
-			return errorf("elf object but not mips")
-		}
-
-	case sys.MIPS64:
-		if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass64 {
-			return errorf("elf object but not mips64")
-		}
-
-	case sys.ARM:
-		if e != binary.LittleEndian || elfobj.machine != ElfMachArm || hdr.Ident[4] != ElfClass32 {
-			return errorf("elf object but not arm")
-		}
-
-	case sys.AMD64:
-		if e != binary.LittleEndian || elfobj.machine != ElfMachAmd64 || hdr.Ident[4] != ElfClass64 {
-			return errorf("elf object but not amd64")
-		}
-
-	case sys.ARM64:
-		if e != binary.LittleEndian || elfobj.machine != ElfMachArm64 || hdr.Ident[4] != ElfClass64 {
-			return errorf("elf object but not arm64")
-		}
-
-	case sys.I386:
-		if e != binary.LittleEndian || elfobj.machine != ElfMach386 || hdr.Ident[4] != ElfClass32 {
-			return errorf("elf object but not 386")
-		}
-
-	case sys.PPC64:
-		if elfobj.machine != ElfMachPower64 || hdr.Ident[4] != ElfClass64 {
-			return errorf("elf object but not ppc64")
-		}
-
-	case sys.S390X:
-		if elfobj.machine != ElfMachS390 || hdr.Ident[4] != ElfClass64 {
-			return errorf("elf object but not s390x")
-		}
-	}
-
-	// load section list into memory.
-	elfobj.sect = make([]ElfSect, elfobj.shnum)
-
-	elfobj.nsect = uint(elfobj.shnum)
-	for i := 0; uint(i) < elfobj.nsect; i++ {
-		f.MustSeek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0)
-		sect := &elfobj.sect[i]
-		if is64 != 0 {
-			var b ElfSectBytes64
-
-			if err := binary.Read(f, e, &b); err != nil {
-				return errorf("malformed elf file: %v", err)
-			}
-
-			sect.nameoff = e.Uint32(b.Name[:])
-			sect.type_ = e.Uint32(b.Type[:])
-			sect.flags = e.Uint64(b.Flags[:])
-			sect.addr = e.Uint64(b.Addr[:])
-			sect.off = e.Uint64(b.Off[:])
-			sect.size = e.Uint64(b.Size[:])
-			sect.link = e.Uint32(b.Link[:])
-			sect.info = e.Uint32(b.Info[:])
-			sect.align = e.Uint64(b.Align[:])
-			sect.entsize = e.Uint64(b.Entsize[:])
-		} else {
-			var b ElfSectBytes
-
-			if err := binary.Read(f, e, &b); err != nil {
-				return errorf("malformed elf file: %v", err)
-			}
-
-			sect.nameoff = e.Uint32(b.Name[:])
-			sect.type_ = e.Uint32(b.Type[:])
-			sect.flags = uint64(e.Uint32(b.Flags[:]))
-			sect.addr = uint64(e.Uint32(b.Addr[:]))
-			sect.off = uint64(e.Uint32(b.Off[:]))
-			sect.size = uint64(e.Uint32(b.Size[:]))
-			sect.link = e.Uint32(b.Link[:])
-			sect.info = e.Uint32(b.Info[:])
-			sect.align = uint64(e.Uint32(b.Align[:]))
-			sect.entsize = uint64(e.Uint32(b.Entsize[:]))
-		}
-	}
-
-	// read section string table and translate names
-	if elfobj.shstrndx >= uint32(elfobj.nsect) {
-		return errorf("malformed elf file: shstrndx out of range %d >= %d", elfobj.shstrndx, elfobj.nsect)
-	}
-
-	sect := &elfobj.sect[elfobj.shstrndx]
-	if err := elfmap(elfobj, sect); err != nil {
-		return errorf("malformed elf file: %v", err)
-	}
-	for i := 0; uint(i) < elfobj.nsect; i++ {
-		if elfobj.sect[i].nameoff != 0 {
-			elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:])
-		}
-	}
-
-	// load string table for symbols into memory.
-	elfobj.symtab = section(elfobj, ".symtab")
-
-	if elfobj.symtab == nil {
-		// our work is done here - no symbols means nothing can refer to this file
-		return
-	}
-
-	if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) {
-		return errorf("elf object has symbol table with invalid string table link")
-	}
-
-	elfobj.symstr = &elfobj.sect[elfobj.symtab.link]
-	if is64 != 0 {
-		elfobj.nsymtab = int(elfobj.symtab.size / ELF64SYMSIZE)
-	} else {
-		elfobj.nsymtab = int(elfobj.symtab.size / ELF32SYMSIZE)
-	}
-
-	if err := elfmap(elfobj, elfobj.symtab); err != nil {
-		return errorf("malformed elf file: %v", err)
-	}
-	if err := elfmap(elfobj, elfobj.symstr); err != nil {
-		return errorf("malformed elf file: %v", err)
-	}
-
-	// load text and data segments into memory.
-	// they are not as small as the section lists, but we'll need
-	// the memory anyway for the symbol images, so we might
-	// as well use one large chunk.
-
-	// create symbols for elfmapped sections
-	sectsymNames := make(map[string]bool)
-	counter := 0
-	for i := 0; uint(i) < elfobj.nsect; i++ {
-		sect = &elfobj.sect[i]
-		if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" {
-			if err := elfmap(elfobj, sect); err != nil {
-				return errorf("%s: malformed elf file: %v", pn, err)
-			}
-			// We assume the soft-float ABI unless we see a tag indicating otherwise.
-			if initEhdrFlags == 0x5000002 {
-				ehdrFlags = 0x5000202
-			} else {
-				ehdrFlags = initEhdrFlags
-			}
-			found, newEhdrFlags, err := parseArmAttributes(e, sect.base[:sect.size])
-			if err != nil {
-				// TODO(dfc) should this return an error?
-				log.Printf("%s: %v", pn, err)
-			}
-			if found {
-				ehdrFlags = newEhdrFlags
-			}
-		}
-		if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 {
-			continue
-		}
-		if sect.type_ != ElfSectNobits {
-			if err := elfmap(elfobj, sect); err != nil {
-				return errorf("%s: malformed elf file: %v", pn, err)
-			}
-		}
-
-		name := fmt.Sprintf("%s(%s)", pkg, sect.name)
-		for sectsymNames[name] {
-			counter++
-			name = fmt.Sprintf("%s(%s%d)", pkg, sect.name, counter)
-		}
-		sectsymNames[name] = true
-
-		s := lookup(name, localSymVersion)
-
-		switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) {
-		default:
-			return errorf("%s: unexpected flags for ELF section %s", pn, sect.name)
-
-		case ElfSectFlagAlloc:
-			s.Type = sym.SRODATA
-
-		case ElfSectFlagAlloc + ElfSectFlagWrite:
-			if sect.type_ == ElfSectNobits {
-				s.Type = sym.SNOPTRBSS
-			} else {
-				s.Type = sym.SNOPTRDATA
-			}
-
-		case ElfSectFlagAlloc + ElfSectFlagExec:
-			s.Type = sym.STEXT
-		}
-
-		if sect.name == ".got" || sect.name == ".toc" {
-			s.Type = sym.SELFGOT
-		}
-		if sect.type_ == ElfSectProgbits {
-			s.P = sect.base
-			s.P = s.P[:sect.size]
-		}
-
-		s.Size = int64(sect.size)
-		s.Align = int32(sect.align)
-		sect.sym = s
-	}
-
-	// enter sub-symbols into symbol table.
-	// symbol 0 is the null symbol.
-	symbols := make([]*sym.Symbol, elfobj.nsymtab)
-
-	for i := 1; i < elfobj.nsymtab; i++ {
-		var elfsym ElfSym
-		if err := readelfsym(newSym, lookup, arch, elfobj, i, &elfsym, 1, localSymVersion); err != nil {
-			return errorf("%s: malformed elf file: %v", pn, err)
-		}
-		symbols[i] = elfsym.sym
-		if elfsym.type_ != ElfSymTypeFunc && elfsym.type_ != ElfSymTypeObject && elfsym.type_ != ElfSymTypeNone && elfsym.type_ != ElfSymTypeCommon {
-			continue
-		}
-		if elfsym.shndx == ElfSymShnCommon || elfsym.type_ == ElfSymTypeCommon {
-			s := elfsym.sym
-			if uint64(s.Size) < elfsym.size {
-				s.Size = int64(elfsym.size)
-			}
-			if s.Type == 0 || s.Type == sym.SXREF {
-				s.Type = sym.SNOPTRBSS
-			}
-			continue
-		}
-
-		if uint(elfsym.shndx) >= elfobj.nsect || elfsym.shndx == 0 {
-			continue
-		}
-
-		// even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols
-		if elfsym.sym == nil {
-			continue
-		}
-		sect = &elfobj.sect[elfsym.shndx]
-		if sect.sym == nil {
-			if strings.HasPrefix(elfsym.name, ".Linfo_string") { // clang does this
-				continue
-			}
-
-			if elfsym.name == "" && elfsym.type_ == 0 && sect.name == ".debug_str" {
-				// This reportedly happens with clang 3.7 on ARM.
-				// See issue 13139.
-				continue
-			}
-
-			if strings.HasPrefix(elfsym.name, "$d") && elfsym.type_ == 0 && sect.name == ".debug_frame" {
-				// "$d" is a marker, not a real symbol.
-				// This happens with gcc on ARM64.
-				// See https://sourceware.org/bugzilla/show_bug.cgi?id=21809
-				continue
-			}
-
-			if strings.HasPrefix(elfsym.name, ".LASF") { // gcc on s390x does this
-				continue
-			}
-			return errorf("%v: sym#%d: ignoring symbol in section %d (type %d)", elfsym.sym, i, elfsym.shndx, elfsym.type_)
-		}
-
-		s := elfsym.sym
-		if s.Outer != nil {
-			if s.Attr.DuplicateOK() {
-				continue
-			}
-			return errorf("duplicate symbol reference: %s in both %s and %s", s.Name, s.Outer.Name, sect.sym.Name)
-		}
-
-		s.Sub = sect.sym.Sub
-		sect.sym.Sub = s
-		s.Type = sect.sym.Type
-		s.Attr |= sym.AttrSubSymbol
-		if !s.Attr.CgoExportDynamic() {
-			s.SetDynimplib("") // satisfy dynimport
-		}
-		s.Value = int64(elfsym.value)
-		s.Size = int64(elfsym.size)
-		s.Outer = sect.sym
-		if sect.sym.Type == sym.STEXT {
-			if s.Attr.External() && !s.Attr.DuplicateOK() {
-				return errorf("%v: duplicate symbol definition", s)
-			}
-			s.Attr |= sym.AttrExternal
-		}
-
-		if elfobj.machine == ElfMachPower64 {
-			flag := int(elfsym.other) >> 5
-			if 2 <= flag && flag <= 6 {
-				s.SetLocalentry(1 << uint(flag-2))
-			} else if flag == 7 {
-				return errorf("%v: invalid sym.other 0x%x", s, elfsym.other)
-			}
-		}
-	}
-
-	// Sort outer lists by address, adding to textp.
-	// This keeps textp in increasing address order.
-	for i := uint(0); i < elfobj.nsect; i++ {
-		s := elfobj.sect[i].sym
-		if s == nil {
-			continue
-		}
-		if s.Sub != nil {
-			s.Sub = sym.SortSub(s.Sub)
-		}
-		if s.Type == sym.STEXT {
-			if s.Attr.OnList() {
-				return errorf("symbol %s listed multiple times", s.Name)
-			}
-			s.Attr |= sym.AttrOnList
-			textp = append(textp, s)
-			for s = s.Sub; s != nil; s = s.Sub {
-				if s.Attr.OnList() {
-					return errorf("symbol %s listed multiple times", s.Name)
-				}
-				s.Attr |= sym.AttrOnList
-				textp = append(textp, s)
-			}
-		}
-	}
-
-	// load relocations
-	for i := uint(0); i < elfobj.nsect; i++ {
-		rsect := &elfobj.sect[i]
-		if rsect.type_ != ElfSectRela && rsect.type_ != ElfSectRel {
-			continue
-		}
-		if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil {
-			continue
-		}
-		sect = &elfobj.sect[rsect.info]
-		if err := elfmap(elfobj, rsect); err != nil {
-			return errorf("malformed elf file: %v", err)
-		}
-		rela := 0
-		if rsect.type_ == ElfSectRela {
-			rela = 1
-		}
-		n := int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
-		r := make([]sym.Reloc, n)
-		p := rsect.base
-		for j := 0; j < n; j++ {
-			var add uint64
-			var symIdx int
-			var relocType uint64
-
-			rp := &r[j]
-			if is64 != 0 {
-				// 64-bit rel/rela
-				rp.Off = int32(e.Uint64(p))
-
-				p = p[8:]
-				switch arch.Family {
-				case sys.MIPS64:
-					// https://www.linux-mips.org/pub/linux/mips/doc/ABI/elf64-2.4.pdf
-					// The doc shows it's different with general Linux ELF
-					symIdx = int(e.Uint32(p))
-					relocType = uint64(p[7])
-				default:
-					info := e.Uint64(p)
-					relocType = info & 0xffffffff
-					symIdx = int(info >> 32)
-				}
-				p = p[8:]
-				if rela != 0 {
-					add = e.Uint64(p)
-					p = p[8:]
-				}
-			} else {
-				// 32-bit rel/rela
-				rp.Off = int32(e.Uint32(p))
-
-				p = p[4:]
-				info := e.Uint32(p)
-				relocType = uint64(info & 0xff)
-				symIdx = int(info >> 8)
-				p = p[4:]
-				if rela != 0 {
-					add = uint64(e.Uint32(p))
-					p = p[4:]
-				}
-			}
-
-			if relocType == 0 { // skip R_*_NONE relocation
-				j--
-				n--
-				continue
-			}
-
-			if symIdx == 0 { // absolute relocation, don't bother reading the null symbol
-				rp.Sym = nil
-			} else {
-				var elfsym ElfSym
-				if err := readelfsym(newSym, lookup, arch, elfobj, symIdx, &elfsym, 0, 0); err != nil {
-					return errorf("malformed elf file: %v", err)
-				}
-				elfsym.sym = symbols[symIdx]
-				if elfsym.sym == nil {
-					return errorf("malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", sect.sym.Name, j, symIdx, elfsym.name, elfsym.shndx, elfsym.type_)
-				}
-
-				rp.Sym = elfsym.sym
-			}
-
-			rp.Type = objabi.ElfRelocOffset + objabi.RelocType(relocType)
-			rp.Siz, err = relSize(arch, pn, uint32(relocType))
-			if err != nil {
-				return nil, 0, err
-			}
-			if rela != 0 {
-				rp.Add = int64(add)
-			} else {
-				// load addend from image
-				if rp.Siz == 4 {
-					rp.Add = int64(e.Uint32(sect.base[rp.Off:]))
-				} else if rp.Siz == 8 {
-					rp.Add = int64(e.Uint64(sect.base[rp.Off:]))
-				} else {
-					return errorf("invalid rela size %d", rp.Siz)
-				}
-			}
-
-			if rp.Siz == 2 {
-				rp.Add = int64(int16(rp.Add))
-			}
-			if rp.Siz == 4 {
-				rp.Add = int64(int32(rp.Add))
-			}
-		}
-
-		//print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add);
-		sort.Sort(sym.RelocByOff(r[:n]))
-		// just in case
-
-		s := sect.sym
-		s.R = r
-		s.R = s.R[:n]
-	}
-
-	return textp, ehdrFlags, nil
-}
-
-func section(elfobj *ElfObj, name string) *ElfSect {
-	for i := 0; uint(i) < elfobj.nsect; i++ {
-		if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name {
-			return &elfobj.sect[i]
-		}
-	}
-	return nil
-}
-
-func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
-	if sect.base != nil {
-		return nil
-	}
-
-	if sect.off+sect.size > uint64(elfobj.length) {
-		err = fmt.Errorf("elf section past end of file")
-		return err
-	}
-
-	sect.base = make([]byte, sect.size)
-	elfobj.f.MustSeek(int64(uint64(elfobj.base)+sect.off), 0)
-	if _, err := io.ReadFull(elfobj.f, sect.base); err != nil {
-		return fmt.Errorf("short read: %v", err)
-	}
-
-	return nil
-}
-
-func readelfsym(newSym, lookup lookupFunc, arch *sys.Arch, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, localSymVersion int) (err error) {
-	if i >= elfobj.nsymtab || i < 0 {
-		err = fmt.Errorf("invalid elf symbol index")
-		return err
-	}
-
-	if i == 0 {
-		return fmt.Errorf("readym: read null symbol!")
-	}
-
-	if elfobj.is64 != 0 {
-		b := new(ElfSymBytes64)
-		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF64SYMSIZE:(i+1)*ELF64SYMSIZE]), elfobj.e, b)
-		elfsym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
-		elfsym.value = elfobj.e.Uint64(b.Value[:])
-		elfsym.size = elfobj.e.Uint64(b.Size[:])
-		elfsym.shndx = elfobj.e.Uint16(b.Shndx[:])
-		elfsym.bind = b.Info >> 4
-		elfsym.type_ = b.Info & 0xf
-		elfsym.other = b.Other
-	} else {
-		b := new(ElfSymBytes)
-		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b)
-		elfsym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
-		elfsym.value = uint64(elfobj.e.Uint32(b.Value[:]))
-		elfsym.size = uint64(elfobj.e.Uint32(b.Size[:]))
-		elfsym.shndx = elfobj.e.Uint16(b.Shndx[:])
-		elfsym.bind = b.Info >> 4
-		elfsym.type_ = b.Info & 0xf
-		elfsym.other = b.Other
-	}
-
-	var s *sym.Symbol
-	if elfsym.name == "_GLOBAL_OFFSET_TABLE_" {
-		elfsym.name = ".got"
-	}
-	if elfsym.name == ".TOC." {
-		// Magic symbol on ppc64.  Will be set to this object
-		// file's .got+0x8000.
-		elfsym.bind = ElfSymBindLocal
-	}
-
-	switch elfsym.type_ {
-	case ElfSymTypeSection:
-		s = elfobj.sect[elfsym.shndx].sym
-
-	case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone, ElfSymTypeCommon:
-		switch elfsym.bind {
-		case ElfSymBindGlobal:
-			if needSym != 0 {
-				s = lookup(elfsym.name, 0)
-
-				// for global scoped hidden symbols we should insert it into
-				// symbol hash table, but mark them as hidden.
-				// __i686.get_pc_thunk.bx is allowed to be duplicated, to
-				// workaround that we set dupok.
-				// TODO(minux): correctly handle __i686.get_pc_thunk.bx without
-				// set dupok generally. See https://golang.org/cl/5823055
-				// comment #5 for details.
-				if s != nil && elfsym.other == 2 {
-					s.Attr |= sym.AttrDuplicateOK | sym.AttrVisibilityHidden
-				}
-			}
-
-		case ElfSymBindLocal:
-			if (arch.Family == sys.ARM || arch.Family == sys.ARM64) && (strings.HasPrefix(elfsym.name, "$a") || strings.HasPrefix(elfsym.name, "$d") || strings.HasPrefix(elfsym.name, "$x")) {
-				// binutils for arm and arm64 generate these mapping
-				// symbols, ignore these
-				break
-			}
-
-			if elfsym.name == ".TOC." {
-				// We need to be able to look this up,
-				// so put it in the hash table.
-				if needSym != 0 {
-					s = lookup(elfsym.name, localSymVersion)
-					s.Attr |= sym.AttrVisibilityHidden
-				}
-
-				break
-			}
-
-			if needSym != 0 {
-				// local names and hidden global names are unique
-				// and should only be referenced by their index, not name, so we
-				// don't bother to add them into the hash table
-				// FIXME: pass empty string here for name? This would
-				// reduce mem use, but also (possibly) make it harder
-				// to debug problems.
-				s = newSym(elfsym.name, localSymVersion)
-
-				s.Attr |= sym.AttrVisibilityHidden
-			}
-
-		case ElfSymBindWeak:
-			if needSym != 0 {
-				s = lookup(elfsym.name, 0)
-				if elfsym.other == 2 {
-					s.Attr |= sym.AttrVisibilityHidden
-				}
-
-				// Allow weak symbols to be duplicated when already defined.
-				if s.Outer != nil {
-					s.Attr |= sym.AttrDuplicateOK
-				}
-			}
-
-		default:
-			err = fmt.Errorf("%s: invalid symbol binding %d", elfsym.name, elfsym.bind)
-			return err
-		}
-	}
-
-	// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
-	// sense and should be removed when someone has thought about it properly.
-	if s != nil && s.Type == 0 && !s.Attr.VisibilityHidden() && elfsym.type_ != ElfSymTypeSection {
-		s.Type = sym.SXREF
-	}
-	elfsym.sym = s
-
-	return nil
-}
-
-func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
-	// TODO(mdempsky): Replace this with a struct-valued switch statement
-	// once golang.org/issue/15164 is fixed or found to not impair cmd/link
-	// performance.
-
-	const (
-		AMD64  = uint32(sys.AMD64)
-		ARM    = uint32(sys.ARM)
-		ARM64  = uint32(sys.ARM64)
-		I386   = uint32(sys.I386)
-		PPC64  = uint32(sys.PPC64)
-		S390X  = uint32(sys.S390X)
-		MIPS   = uint32(sys.MIPS)
-		MIPS64 = uint32(sys.MIPS64)
-	)
-
-	switch uint32(arch.Family) | elftype<<16 {
-	default:
-		return 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
-
-	case MIPS | uint32(elf.R_MIPS_HI16)<<16,
-		MIPS | uint32(elf.R_MIPS_LO16)<<16,
-		MIPS | uint32(elf.R_MIPS_GOT16)<<16,
-		MIPS | uint32(elf.R_MIPS_GPREL16)<<16,
-		MIPS | uint32(elf.R_MIPS_GOT_PAGE)<<16,
-		MIPS | uint32(elf.R_MIPS_JALR)<<16,
-		MIPS | uint32(elf.R_MIPS_GOT_OFST)<<16,
-		MIPS64 | uint32(elf.R_MIPS_HI16)<<16,
-		MIPS64 | uint32(elf.R_MIPS_LO16)<<16,
-		MIPS64 | uint32(elf.R_MIPS_GOT16)<<16,
-		MIPS64 | uint32(elf.R_MIPS_GPREL16)<<16,
-		MIPS64 | uint32(elf.R_MIPS_GOT_PAGE)<<16,
-		MIPS64 | uint32(elf.R_MIPS_JALR)<<16,
-		MIPS64 | uint32(elf.R_MIPS_GOT_OFST)<<16:
-		return 4, nil
-
-	case S390X | uint32(elf.R_390_8)<<16:
-		return 1, nil
-
-	case PPC64 | uint32(elf.R_PPC64_TOC16)<<16,
-		PPC64 | uint32(elf.R_PPC64_TOC16_LO)<<16,
-		PPC64 | uint32(elf.R_PPC64_TOC16_HI)<<16,
-		PPC64 | uint32(elf.R_PPC64_TOC16_HA)<<16,
-		PPC64 | uint32(elf.R_PPC64_TOC16_DS)<<16,
-		PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<16,
-		PPC64 | uint32(elf.R_PPC64_REL16_LO)<<16,
-		PPC64 | uint32(elf.R_PPC64_REL16_HI)<<16,
-		PPC64 | uint32(elf.R_PPC64_REL16_HA)<<16,
-		S390X | uint32(elf.R_390_16)<<16,
-		S390X | uint32(elf.R_390_GOT16)<<16,
-		S390X | uint32(elf.R_390_PC16)<<16,
-		S390X | uint32(elf.R_390_PC16DBL)<<16,
-		S390X | uint32(elf.R_390_PLT16DBL)<<16:
-		return 2, nil
-
-	case ARM | uint32(elf.R_ARM_ABS32)<<16,
-		ARM | uint32(elf.R_ARM_GOT32)<<16,
-		ARM | uint32(elf.R_ARM_PLT32)<<16,
-		ARM | uint32(elf.R_ARM_GOTOFF)<<16,
-		ARM | uint32(elf.R_ARM_GOTPC)<<16,
-		ARM | uint32(elf.R_ARM_THM_PC22)<<16,
-		ARM | uint32(elf.R_ARM_REL32)<<16,
-		ARM | uint32(elf.R_ARM_CALL)<<16,
-		ARM | uint32(elf.R_ARM_V4BX)<<16,
-		ARM | uint32(elf.R_ARM_GOT_PREL)<<16,
-		ARM | uint32(elf.R_ARM_PC24)<<16,
-		ARM | uint32(elf.R_ARM_JUMP24)<<16,
-		ARM64 | uint32(elf.R_AARCH64_CALL26)<<16,
-		ARM64 | uint32(elf.R_AARCH64_ADR_GOT_PAGE)<<16,
-		ARM64 | uint32(elf.R_AARCH64_LD64_GOT_LO12_NC)<<16,
-		ARM64 | uint32(elf.R_AARCH64_ADR_PREL_PG_HI21)<<16,
-		ARM64 | uint32(elf.R_AARCH64_ADD_ABS_LO12_NC)<<16,
-		ARM64 | uint32(elf.R_AARCH64_LDST8_ABS_LO12_NC)<<16,
-		ARM64 | uint32(elf.R_AARCH64_LDST32_ABS_LO12_NC)<<16,
-		ARM64 | uint32(elf.R_AARCH64_LDST64_ABS_LO12_NC)<<16,
-		ARM64 | uint32(elf.R_AARCH64_LDST128_ABS_LO12_NC)<<16,
-		ARM64 | uint32(elf.R_AARCH64_PREL32)<<16,
-		ARM64 | uint32(elf.R_AARCH64_JUMP26)<<16,
-		AMD64 | uint32(elf.R_X86_64_PC32)<<16,
-		AMD64 | uint32(elf.R_X86_64_PLT32)<<16,
-		AMD64 | uint32(elf.R_X86_64_GOTPCREL)<<16,
-		AMD64 | uint32(elf.R_X86_64_GOTPCRELX)<<16,
-		AMD64 | uint32(elf.R_X86_64_REX_GOTPCRELX)<<16,
-		I386 | uint32(elf.R_386_32)<<16,
-		I386 | uint32(elf.R_386_PC32)<<16,
-		I386 | uint32(elf.R_386_GOT32)<<16,
-		I386 | uint32(elf.R_386_PLT32)<<16,
-		I386 | uint32(elf.R_386_GOTOFF)<<16,
-		I386 | uint32(elf.R_386_GOTPC)<<16,
-		I386 | uint32(elf.R_386_GOT32X)<<16,
-		PPC64 | uint32(elf.R_PPC64_REL24)<<16,
-		PPC64 | uint32(elf.R_PPC_REL32)<<16,
-		S390X | uint32(elf.R_390_32)<<16,
-		S390X | uint32(elf.R_390_PC32)<<16,
-		S390X | uint32(elf.R_390_GOT32)<<16,
-		S390X | uint32(elf.R_390_PLT32)<<16,
-		S390X | uint32(elf.R_390_PC32DBL)<<16,
-		S390X | uint32(elf.R_390_PLT32DBL)<<16,
-		S390X | uint32(elf.R_390_GOTPCDBL)<<16,
-		S390X | uint32(elf.R_390_GOTENT)<<16:
-		return 4, nil
-
-	case AMD64 | uint32(elf.R_X86_64_64)<<16,
-		AMD64 | uint32(elf.R_X86_64_PC64)<<16,
-		ARM64 | uint32(elf.R_AARCH64_ABS64)<<16,
-		ARM64 | uint32(elf.R_AARCH64_PREL64)<<16,
-		PPC64 | uint32(elf.R_PPC64_ADDR64)<<16,
-		S390X | uint32(elf.R_390_GLOB_DAT)<<16,
-		S390X | uint32(elf.R_390_RELATIVE)<<16,
-		S390X | uint32(elf.R_390_GOTOFF)<<16,
-		S390X | uint32(elf.R_390_GOTPC)<<16,
-		S390X | uint32(elf.R_390_64)<<16,
-		S390X | uint32(elf.R_390_PC64)<<16,
-		S390X | uint32(elf.R_390_GOT64)<<16,
-		S390X | uint32(elf.R_390_PLT64)<<16:
-		return 8, nil
-	}
-}
-
-func cstring(x []byte) string {
-	i := bytes.IndexByte(x, '\x00')
-	if i >= 0 {
-		x = x[:i]
-	}
-	return string(x)
-}
diff --git a/src/cmd/oldlink/internal/loader/loader.go b/src/cmd/oldlink/internal/loader/loader.go
deleted file mode 100644
index 8c618bf..0000000
--- a/src/cmd/oldlink/internal/loader/loader.go
+++ /dev/null
@@ -1,629 +0,0 @@
-// Copyright 2019 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 loader
-
-import (
-	"bytes"
-	"cmd/internal/bio"
-	"cmd/internal/dwarf"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/sym"
-	"fmt"
-	"log"
-	"sort"
-	"strconv"
-	"strings"
-)
-
-var _ = fmt.Print
-
-// Sym encapsulates a global symbol index, used to identify a specific
-// Go symbol. The 0-valued Sym is corresponds to an invalid symbol.
-type Sym int
-
-// Relocs encapsulates the set of relocations on a given symbol; an
-// instance of this type is returned by the Loader Relocs() method.
-type Relocs struct {
-	Count int // number of relocs
-
-	li int      // local index of symbol whose relocs we're examining
-	r  *oReader // object reader for containing package
-	l  *Loader  // loader
-
-	ext *sym.Symbol // external symbol if not nil
-}
-
-// Reloc contains the payload for a specific relocation.
-// TODO: replace this with sym.Reloc, once we change the
-// relocation target from "*sym.Symbol" to "loader.Sym" in sym.Reloc.
-type Reloc struct {
-	Off  int32            // offset to rewrite
-	Size uint8            // number of bytes to rewrite: 0, 1, 2, or 4
-	Type objabi.RelocType // the relocation type
-	Add  int64            // addend
-	Sym  Sym              // global index of symbol the reloc addresses
-}
-
-// oReader is a wrapper type of obj.Reader, along with some
-// extra information.
-// TODO: rename to objReader once the old one is gone?
-type oReader struct {
-	//*goobj2.Reader
-	unit      *sym.CompilationUnit
-	version   int    // version of static symbol
-	flags     uint32 // read from object file
-	pkgprefix string
-	rcache    []Sym // cache mapping local PkgNone symbol to resolved Sym
-}
-
-type objIdx struct {
-	r *oReader
-	i Sym // start index
-	e Sym // end index
-}
-
-type nameVer struct {
-	name string
-	v    int
-}
-
-type bitmap []uint32
-
-// set the i-th bit.
-func (bm bitmap) Set(i Sym) {
-	n, r := uint(i)/32, uint(i)%32
-	bm[n] |= 1 << r
-}
-
-// whether the i-th bit is set.
-func (bm bitmap) Has(i Sym) bool {
-	n, r := uint(i)/32, uint(i)%32
-	return bm[n]&(1<<r) != 0
-}
-
-func makeBitmap(n int) bitmap {
-	return make(bitmap, (n+31)/32)
-}
-
-// A Loader loads new object files and resolves indexed symbol references.
-type Loader struct {
-	start       map[*oReader]Sym // map from object file to its start index
-	objs        []objIdx         // sorted by start index (i.e. objIdx.i)
-	max         Sym              // current max index
-	extStart    Sym              // from this index on, the symbols are externally defined
-	extSyms     []nameVer        // externally defined symbols
-	builtinSyms []Sym            // global index of builtin symbols
-	ocache      int              // index (into 'objs') of most recent lookup
-
-	symsByName    [2]map[string]Sym // map symbol name to index, two maps are for ABI0 and ABIInternal
-	extStaticSyms map[nameVer]Sym   // externally defined static symbols, keyed by name
-	overwrite     map[Sym]Sym       // overwrite[i]=j if symbol j overwrites symbol i
-
-	itablink map[Sym]struct{} // itablink[j] defined if j is go.itablink.*
-
-	objByPkg map[string]*oReader // map package path to its Go object reader
-
-	Syms []*sym.Symbol // indexed symbols. XXX we still make sym.Symbol for now.
-
-	anonVersion int // most recently assigned ext static sym pseudo-version
-
-	Reachable bitmap // bitmap of reachable symbols, indexed by global index
-
-	// Used to implement field tracking; created during deadcode if
-	// field tracking is enabled. Reachparent[K] contains the index of
-	// the symbol that triggered the marking of symbol K as live.
-	Reachparent []Sym
-
-	relocBatch []sym.Reloc // for bulk allocation of relocations
-
-	flags uint32
-
-	strictDupMsgs int // number of strict-dup warning/errors, when FlagStrictDups is enabled
-}
-
-const (
-	// Loader.flags
-	FlagStrictDups = 1 << iota
-)
-
-func NewLoader(flags uint32) *Loader {
-	log.Fatal("-newobj in oldlink should not be used")
-	panic("unreachable")
-}
-
-// Return the start index in the global index space for a given object file.
-func (l *Loader) startIndex(r *oReader) Sym {
-	return l.start[r]
-}
-
-// Add a symbol with a given index, return if it is added.
-func (l *Loader) AddSym(name string, ver int, i Sym, r *oReader, dupok bool, typ sym.SymKind) bool {
-	panic("unreachable")
-}
-
-// Add an external symbol (without index). Return the index of newly added
-// symbol, or 0 if not added.
-func (l *Loader) AddExtSym(name string, ver int) Sym {
-	static := ver >= sym.SymVerStatic
-	if static {
-		if _, ok := l.extStaticSyms[nameVer{name, ver}]; ok {
-			return 0
-		}
-	} else {
-		if _, ok := l.symsByName[ver][name]; ok {
-			return 0
-		}
-	}
-	i := l.max + 1
-	if static {
-		l.extStaticSyms[nameVer{name, ver}] = i
-	} else {
-		l.symsByName[ver][name] = i
-	}
-	l.max++
-	if l.extStart == 0 {
-		l.extStart = i
-	}
-	l.extSyms = append(l.extSyms, nameVer{name, ver})
-	l.growSyms(int(i))
-	return i
-}
-
-func (l *Loader) IsExternal(i Sym) bool {
-	return l.extStart != 0 && i >= l.extStart
-}
-
-// Ensure Syms slice has enough space.
-func (l *Loader) growSyms(i int) {
-	n := len(l.Syms)
-	if n > i {
-		return
-	}
-	l.Syms = append(l.Syms, make([]*sym.Symbol, i+1-n)...)
-}
-
-// Convert a local index to a global index.
-func (l *Loader) toGlobal(r *oReader, i int) Sym {
-	g := l.startIndex(r) + Sym(i)
-	if ov, ok := l.overwrite[g]; ok {
-		return ov
-	}
-	return g
-}
-
-// Convert a global index to a local index.
-func (l *Loader) toLocal(i Sym) (*oReader, int) {
-	if ov, ok := l.overwrite[i]; ok {
-		i = ov
-	}
-	if l.IsExternal(i) {
-		return nil, int(i - l.extStart)
-	}
-	oc := l.ocache
-	if oc != 0 && i >= l.objs[oc].i && i <= l.objs[oc].e {
-		return l.objs[oc].r, int(i - l.objs[oc].i)
-	}
-	// Search for the local object holding index i.
-	// Below k is the first one that has its start index > i,
-	// so k-1 is the one we want.
-	k := sort.Search(len(l.objs), func(k int) bool {
-		return l.objs[k].i > i
-	})
-	l.ocache = k - 1
-	return l.objs[k-1].r, int(i - l.objs[k-1].i)
-}
-
-// Look up a symbol by name, return global index, or 0 if not found.
-// This is more like Syms.ROLookup than Lookup -- it doesn't create
-// new symbol.
-func (l *Loader) Lookup(name string, ver int) Sym {
-	if ver >= sym.SymVerStatic || ver < 0 {
-		return l.extStaticSyms[nameVer{name, ver}]
-	}
-	return l.symsByName[ver][name]
-}
-
-// Returns whether i is a dup of another symbol, and i is not
-// "primary", i.e. Lookup i by name will not return i.
-func (l *Loader) IsDup(i Sym) bool {
-	panic("unreachable")
-}
-
-// Check that duplicate symbols have same contents.
-func (l *Loader) checkdup(name string, i Sym, r *oReader, dup Sym) {
-	panic("unreachable")
-}
-
-func (l *Loader) NStrictDupMsgs() int { return l.strictDupMsgs }
-
-// Number of total symbols.
-func (l *Loader) NSym() int {
-	return int(l.max + 1)
-}
-
-// Number of defined Go symbols.
-func (l *Loader) NDef() int {
-	return int(l.extStart)
-}
-
-// Returns the raw (unpatched) name of the i-th symbol.
-func (l *Loader) RawSymName(i Sym) string {
-	panic("unreachable")
-}
-
-// Returns the (patched) name of the i-th symbol.
-func (l *Loader) SymName(i Sym) string {
-	panic("unreachable")
-}
-
-// Returns the type of the i-th symbol.
-func (l *Loader) SymType(i Sym) sym.SymKind {
-	panic("unreachable")
-}
-
-// Returns the attributes of the i-th symbol.
-func (l *Loader) SymAttr(i Sym) uint8 {
-	panic("unreachable")
-}
-
-// Returns whether the i-th symbol has ReflectMethod attribute set.
-func (l *Loader) IsReflectMethod(i Sym) bool {
-	panic("unreachable")
-}
-
-// Returns whether this is a Go type symbol.
-func (l *Loader) IsGoType(i Sym) bool {
-	panic("unreachable")
-}
-
-// Returns whether this is a "go.itablink.*" symbol.
-func (l *Loader) IsItabLink(i Sym) bool {
-	if _, ok := l.itablink[i]; ok {
-		return true
-	}
-	return false
-}
-
-// Returns the symbol content of the i-th symbol. i is global index.
-func (l *Loader) Data(i Sym) []byte {
-	panic("unreachable")
-}
-
-// Returns the number of aux symbols given a global index.
-func (l *Loader) NAux(i Sym) int {
-	panic("unreachable")
-}
-
-// Returns the referred symbol of the j-th aux symbol of the i-th
-// symbol.
-func (l *Loader) AuxSym(i Sym, j int) Sym {
-	panic("unreachable")
-}
-
-// ReadAuxSyms reads the aux symbol ids for the specified symbol into the
-// slice passed as a parameter. If the slice capacity is not large enough, a new
-// larger slice will be allocated. Final slice is returned.
-func (l *Loader) ReadAuxSyms(symIdx Sym, dst []Sym) []Sym {
-	panic("unreachable")
-}
-
-// OuterSym gets the outer symbol for host object loaded symbols.
-func (l *Loader) OuterSym(i Sym) Sym {
-	sym := l.Syms[i]
-	if sym != nil && sym.Outer != nil {
-		outer := sym.Outer
-		return l.Lookup(outer.Name, int(outer.Version))
-	}
-	return 0
-}
-
-// SubSym gets the subsymbol for host object loaded symbols.
-func (l *Loader) SubSym(i Sym) Sym {
-	sym := l.Syms[i]
-	if sym != nil && sym.Sub != nil {
-		sub := sym.Sub
-		return l.Lookup(sub.Name, int(sub.Version))
-	}
-	return 0
-}
-
-// Initialize Reachable bitmap for running deadcode pass.
-func (l *Loader) InitReachable() {
-	l.Reachable = makeBitmap(l.NSym())
-}
-
-// At method returns the j-th reloc for a global symbol.
-func (relocs *Relocs) At(j int) Reloc {
-	panic("unreachable")
-}
-
-// ReadAll method reads all relocations for a symbol into the
-// specified slice. If the slice capacity is not large enough, a new
-// larger slice will be allocated. Final slice is returned.
-func (relocs *Relocs) ReadAll(dst []Reloc) []Reloc {
-	panic("unreachable")
-}
-
-// Relocs returns a Relocs object for the given global sym.
-func (l *Loader) Relocs(i Sym) Relocs {
-	panic("unreachable")
-}
-
-// Preload a package: add autolibs, add symbols to the symbol table.
-// Does not read symbol data yet.
-func (l *Loader) Preload(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, lib *sym.Library, unit *sym.CompilationUnit, length int64, pn string, flags int) {
-	panic("unreachable")
-}
-
-// Make sure referenced symbols are added. Most of them should already be added.
-// This should only be needed for referenced external symbols.
-func (l *Loader) LoadRefs(arch *sys.Arch, syms *sym.Symbols) {
-	for _, o := range l.objs[1:] {
-		loadObjRefs(l, o.r, arch, syms)
-	}
-}
-
-func loadObjRefs(l *Loader, r *oReader, arch *sys.Arch, syms *sym.Symbols) {
-	panic("unreachable")
-}
-
-func abiToVer(abi uint16, localSymVersion int) int {
-	panic("unreachable")
-}
-
-func preprocess(arch *sys.Arch, s *sym.Symbol) {
-	if s.Name != "" && s.Name[0] == '$' && len(s.Name) > 5 && s.Type == 0 && len(s.P) == 0 {
-		x, err := strconv.ParseUint(s.Name[5:], 16, 64)
-		if err != nil {
-			log.Panicf("failed to parse $-symbol %s: %v", s.Name, err)
-		}
-		s.Type = sym.SRODATA
-		s.Attr |= sym.AttrLocal
-		switch s.Name[:5] {
-		case "$f32.":
-			if uint64(uint32(x)) != x {
-				log.Panicf("$-symbol %s too large: %d", s.Name, x)
-			}
-			s.AddUint32(arch, uint32(x))
-		case "$f64.", "$i64.":
-			s.AddUint64(arch, x)
-		default:
-			log.Panicf("unrecognized $-symbol: %s", s.Name)
-		}
-	}
-}
-
-// Load full contents.
-func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols) {
-	// create all Symbols first.
-	l.growSyms(l.NSym())
-
-	nr := 0 // total number of sym.Reloc's we'll need
-	for _, o := range l.objs[1:] {
-		nr += loadObjSyms(l, syms, o.r)
-	}
-
-	// allocate a single large slab of relocations for all live symbols
-	l.relocBatch = make([]sym.Reloc, nr)
-
-	// external symbols
-	for i := l.extStart; i <= l.max; i++ {
-		if s := l.Syms[i]; s != nil {
-			s.Attr.Set(sym.AttrReachable, l.Reachable.Has(i))
-			continue // already loaded from external object
-		}
-		nv := l.extSyms[i-l.extStart]
-		if l.Reachable.Has(i) || strings.HasPrefix(nv.name, "gofile..") { // XXX file symbols are used but not marked
-			s := syms.Newsym(nv.name, nv.v)
-			preprocess(arch, s)
-			s.Attr.Set(sym.AttrReachable, l.Reachable.Has(i))
-			l.Syms[i] = s
-		}
-	}
-
-	// load contents of defined symbols
-	for _, o := range l.objs[1:] {
-		loadObjFull(l, o.r)
-	}
-
-	// Resolve ABI aliases for external symbols. This is only
-	// needed for internal cgo linking.
-	// (The old code does this in deadcode, but deadcode2 doesn't
-	// do this.)
-	for i := l.extStart; i <= l.max; i++ {
-		if s := l.Syms[i]; s != nil && s.Attr.Reachable() {
-			for ri := range s.R {
-				r := &s.R[ri]
-				if r.Sym != nil && r.Sym.Type == sym.SABIALIAS {
-					r.Sym = r.Sym.R[0].Sym
-				}
-			}
-		}
-	}
-}
-
-// ExtractSymbols grabs the symbols out of the loader for work that hasn't been
-// ported to the new symbol type.
-func (l *Loader) ExtractSymbols(syms *sym.Symbols) {
-	// Nil out overwritten symbols.
-	// Overwritten Go symbols aren't a problem (as they're lazy loaded), but
-	// symbols loaded from host object loaders are fully loaded, and we might
-	// have multiple symbols with the same name. This loop nils them out.
-	for oldI := range l.overwrite {
-		l.Syms[oldI] = nil
-	}
-
-	// Add symbols to the ctxt.Syms lookup table. This explicitly
-	// skips things created via loader.Create (marked with versions
-	// less than zero), since if we tried to add these we'd wind up
-	// with collisions. Along the way, update the version from the
-	// negative anon version to something larger than sym.SymVerStatic
-	// (needed so that sym.symbol.IsFileLocal() works properly).
-	anonVerReplacement := syms.IncVersion()
-	for _, s := range l.Syms {
-		if s == nil {
-			continue
-		}
-		if s.Name != "" && s.Version >= 0 {
-			syms.Add(s)
-		}
-		if s.Version < 0 {
-			s.Version = int16(anonVerReplacement)
-		}
-	}
-}
-
-// addNewSym adds a new sym.Symbol to the i-th index in the list of symbols.
-func (l *Loader) addNewSym(i Sym, syms *sym.Symbols, name string, ver int, unit *sym.CompilationUnit, t sym.SymKind) *sym.Symbol {
-	s := syms.Newsym(name, ver)
-	if s.Type != 0 && s.Type != sym.SXREF {
-		fmt.Println("symbol already processed:", unit.Lib, i, s)
-		panic("symbol already processed")
-	}
-	if t == sym.SBSS && (s.Type == sym.SRODATA || s.Type == sym.SNOPTRBSS) {
-		t = s.Type
-	}
-	s.Type = t
-	s.Unit = unit
-	l.growSyms(int(i))
-	l.Syms[i] = s
-	return s
-}
-
-// loadObjSyms creates sym.Symbol objects for the live Syms in the
-// object corresponding to object reader "r". Return value is the
-// number of sym.Reloc entries required for all the new symbols.
-func loadObjSyms(l *Loader, syms *sym.Symbols, r *oReader) int {
-	panic("unreachable")
-}
-
-// LoadSymbol loads a single symbol by name.
-// This function should only be used by the host object loaders.
-// NB: This function does NOT set the symbol as reachable.
-func (l *Loader) LoadSymbol(name string, version int, syms *sym.Symbols) *sym.Symbol {
-	panic("unreachable")
-}
-
-// LookupOrCreate looks up a symbol by name, and creates one if not found.
-// Either way, it will also create a sym.Symbol for it, if not already.
-// This should only be called when interacting with parts of the linker
-// that still works on sym.Symbols (i.e. internal cgo linking, for now).
-func (l *Loader) LookupOrCreate(name string, version int, syms *sym.Symbols) *sym.Symbol {
-	i := l.Lookup(name, version)
-	if i != 0 {
-		// symbol exists
-		if int(i) < len(l.Syms) && l.Syms[i] != nil {
-			return l.Syms[i] // already loaded
-		}
-		if l.IsExternal(i) {
-			panic("Can't load an external symbol.")
-		}
-		return l.LoadSymbol(name, version, syms)
-	}
-	i = l.AddExtSym(name, version)
-	s := syms.Newsym(name, version)
-	l.Syms[i] = s
-	return s
-}
-
-// Create creates a symbol with the specified name, returning a
-// sym.Symbol object for it. This method is intended for static/hidden
-// symbols discovered while loading host objects. We can see more than
-// one instance of a given static symbol with the same name/version,
-// so we can't add them to the lookup tables "as is". Instead assign
-// them fictitious (unique) versions, starting at -1 and decreasing by
-// one for each newly created symbol, and record them in the
-// extStaticSyms hash.
-func (l *Loader) Create(name string, syms *sym.Symbols) *sym.Symbol {
-	i := l.max + 1
-	l.max++
-	if l.extStart == 0 {
-		l.extStart = i
-	}
-
-	// Assign a new unique negative version -- this is to mark the
-	// symbol so that it can be skipped when ExtractSymbols is adding
-	// ext syms to the sym.Symbols hash.
-	l.anonVersion--
-	ver := l.anonVersion
-	l.extSyms = append(l.extSyms, nameVer{name, ver})
-	l.growSyms(int(i))
-	s := syms.Newsym(name, ver)
-	l.Syms[i] = s
-	l.extStaticSyms[nameVer{name, ver}] = i
-
-	return s
-}
-
-func loadObjFull(l *Loader, r *oReader) {
-	panic("unreachable")
-}
-
-var emptyPkg = []byte(`"".`)
-
-func patchDWARFName1(p []byte, r *oReader) ([]byte, int) {
-	// This is kind of ugly. Really the package name should not
-	// even be included here.
-	if len(p) < 1 || p[0] != dwarf.DW_ABRV_FUNCTION {
-		return p, -1
-	}
-	e := bytes.IndexByte(p, 0)
-	if e == -1 {
-		return p, -1
-	}
-	if !bytes.Contains(p[:e], emptyPkg) {
-		return p, -1
-	}
-	pkgprefix := []byte(r.pkgprefix)
-	patched := bytes.Replace(p[:e], emptyPkg, pkgprefix, -1)
-	return append(patched, p[e:]...), e
-}
-
-func patchDWARFName(s *sym.Symbol, r *oReader) {
-	patched, e := patchDWARFName1(s.P, r)
-	if e == -1 {
-		return
-	}
-	s.P = patched
-	s.Attr.Set(sym.AttrReadOnly, false)
-	delta := int64(len(s.P)) - s.Size
-	s.Size = int64(len(s.P))
-	for i := range s.R {
-		r := &s.R[i]
-		if r.Off > int32(e) {
-			r.Off += int32(delta)
-		}
-	}
-}
-
-// For debugging.
-func (l *Loader) Dump() {
-	fmt.Println("objs")
-	for _, obj := range l.objs {
-		if obj.r != nil {
-			fmt.Println(obj.i, obj.r.unit.Lib)
-		}
-	}
-	fmt.Println("syms")
-	for i, s := range l.Syms {
-		if i == 0 {
-			continue
-		}
-		if s != nil {
-			fmt.Println(i, s, s.Type)
-		} else {
-			fmt.Println(i, l.SymName(Sym(i)), "<not loaded>")
-		}
-	}
-	fmt.Println("overwrite:", l.overwrite)
-	fmt.Println("symsByName")
-	for name, i := range l.symsByName[0] {
-		fmt.Println(i, name, 0)
-	}
-	for name, i := range l.symsByName[1] {
-		fmt.Println(i, name, 1)
-	}
-}
diff --git a/src/cmd/oldlink/internal/loadmacho/ldmacho.go b/src/cmd/oldlink/internal/loadmacho/ldmacho.go
deleted file mode 100644
index 4846239..0000000
--- a/src/cmd/oldlink/internal/loadmacho/ldmacho.go
+++ /dev/null
@@ -1,794 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package loadmacho implements a Mach-O file reader.
-package loadmacho
-
-import (
-	"bytes"
-	"cmd/internal/bio"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/loader"
-	"cmd/oldlink/internal/sym"
-	"encoding/binary"
-	"fmt"
-	"io"
-	"sort"
-)
-
-/*
-Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c
-http://code.swtch.com/plan9port/src/tip/src/libmach/
-
-	Copyright © 2004 Russ Cox.
-	Portions Copyright © 2008-2010 Google Inc.
-	Portions Copyright © 2010 The Go Authors.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-// TODO(crawshaw): de-duplicate these symbols with cmd/internal/ld
-const (
-	MACHO_X86_64_RELOC_UNSIGNED = 0
-	MACHO_X86_64_RELOC_SIGNED   = 1
-	MACHO_FAKE_GOTPCREL         = 100
-)
-
-type ldMachoObj struct {
-	f          *bio.Reader
-	base       int64 // off in f where Mach-O begins
-	length     int64 // length of Mach-O
-	is64       bool
-	name       string
-	e          binary.ByteOrder
-	cputype    uint
-	subcputype uint
-	filetype   uint32
-	flags      uint32
-	cmd        []ldMachoCmd
-	ncmd       uint
-}
-
-type ldMachoCmd struct {
-	type_ int
-	off   uint32
-	size  uint32
-	seg   ldMachoSeg
-	sym   ldMachoSymtab
-	dsym  ldMachoDysymtab
-}
-
-type ldMachoSeg struct {
-	name     string
-	vmaddr   uint64
-	vmsize   uint64
-	fileoff  uint32
-	filesz   uint32
-	maxprot  uint32
-	initprot uint32
-	nsect    uint32
-	flags    uint32
-	sect     []ldMachoSect
-}
-
-type ldMachoSect struct {
-	name    string
-	segname string
-	addr    uint64
-	size    uint64
-	off     uint32
-	align   uint32
-	reloff  uint32
-	nreloc  uint32
-	flags   uint32
-	res1    uint32
-	res2    uint32
-	sym     *sym.Symbol
-	rel     []ldMachoRel
-}
-
-type ldMachoRel struct {
-	addr      uint32
-	symnum    uint32
-	pcrel     uint8
-	length    uint8
-	extrn     uint8
-	type_     uint8
-	scattered uint8
-	value     uint32
-}
-
-type ldMachoSymtab struct {
-	symoff  uint32
-	nsym    uint32
-	stroff  uint32
-	strsize uint32
-	str     []byte
-	sym     []ldMachoSym
-}
-
-type ldMachoSym struct {
-	name    string
-	type_   uint8
-	sectnum uint8
-	desc    uint16
-	kind    int8
-	value   uint64
-	sym     *sym.Symbol
-}
-
-type ldMachoDysymtab struct {
-	ilocalsym      uint32
-	nlocalsym      uint32
-	iextdefsym     uint32
-	nextdefsym     uint32
-	iundefsym      uint32
-	nundefsym      uint32
-	tocoff         uint32
-	ntoc           uint32
-	modtaboff      uint32
-	nmodtab        uint32
-	extrefsymoff   uint32
-	nextrefsyms    uint32
-	indirectsymoff uint32
-	nindirectsyms  uint32
-	extreloff      uint32
-	nextrel        uint32
-	locreloff      uint32
-	nlocrel        uint32
-	indir          []uint32
-}
-
-// ldMachoSym.type_
-const (
-	N_EXT  = 0x01
-	N_TYPE = 0x1e
-	N_STAB = 0xe0
-)
-
-// ldMachoSym.desc
-const (
-	N_WEAK_REF = 0x40
-	N_WEAK_DEF = 0x80
-)
-
-const (
-	LdMachoCpuVax         = 1
-	LdMachoCpu68000       = 6
-	LdMachoCpu386         = 7
-	LdMachoCpuAmd64       = 0x1000007
-	LdMachoCpuMips        = 8
-	LdMachoCpu98000       = 10
-	LdMachoCpuHppa        = 11
-	LdMachoCpuArm         = 12
-	LdMachoCpu88000       = 13
-	LdMachoCpuSparc       = 14
-	LdMachoCpu860         = 15
-	LdMachoCpuAlpha       = 16
-	LdMachoCpuPower       = 18
-	LdMachoCmdSegment     = 1
-	LdMachoCmdSymtab      = 2
-	LdMachoCmdSymseg      = 3
-	LdMachoCmdThread      = 4
-	LdMachoCmdDysymtab    = 11
-	LdMachoCmdSegment64   = 25
-	LdMachoFileObject     = 1
-	LdMachoFileExecutable = 2
-	LdMachoFileFvmlib     = 3
-	LdMachoFileCore       = 4
-	LdMachoFilePreload    = 5
-)
-
-func unpackcmd(p []byte, m *ldMachoObj, c *ldMachoCmd, type_ uint, sz uint) int {
-	e4 := m.e.Uint32
-	e8 := m.e.Uint64
-
-	c.type_ = int(type_)
-	c.size = uint32(sz)
-	switch type_ {
-	default:
-		return -1
-
-	case LdMachoCmdSegment:
-		if sz < 56 {
-			return -1
-		}
-		c.seg.name = cstring(p[8:24])
-		c.seg.vmaddr = uint64(e4(p[24:]))
-		c.seg.vmsize = uint64(e4(p[28:]))
-		c.seg.fileoff = e4(p[32:])
-		c.seg.filesz = e4(p[36:])
-		c.seg.maxprot = e4(p[40:])
-		c.seg.initprot = e4(p[44:])
-		c.seg.nsect = e4(p[48:])
-		c.seg.flags = e4(p[52:])
-		c.seg.sect = make([]ldMachoSect, c.seg.nsect)
-		if uint32(sz) < 56+c.seg.nsect*68 {
-			return -1
-		}
-		p = p[56:]
-		var s *ldMachoSect
-		for i := 0; uint32(i) < c.seg.nsect; i++ {
-			s = &c.seg.sect[i]
-			s.name = cstring(p[0:16])
-			s.segname = cstring(p[16:32])
-			s.addr = uint64(e4(p[32:]))
-			s.size = uint64(e4(p[36:]))
-			s.off = e4(p[40:])
-			s.align = e4(p[44:])
-			s.reloff = e4(p[48:])
-			s.nreloc = e4(p[52:])
-			s.flags = e4(p[56:])
-			s.res1 = e4(p[60:])
-			s.res2 = e4(p[64:])
-			p = p[68:]
-		}
-
-	case LdMachoCmdSegment64:
-		if sz < 72 {
-			return -1
-		}
-		c.seg.name = cstring(p[8:24])
-		c.seg.vmaddr = e8(p[24:])
-		c.seg.vmsize = e8(p[32:])
-		c.seg.fileoff = uint32(e8(p[40:]))
-		c.seg.filesz = uint32(e8(p[48:]))
-		c.seg.maxprot = e4(p[56:])
-		c.seg.initprot = e4(p[60:])
-		c.seg.nsect = e4(p[64:])
-		c.seg.flags = e4(p[68:])
-		c.seg.sect = make([]ldMachoSect, c.seg.nsect)
-		if uint32(sz) < 72+c.seg.nsect*80 {
-			return -1
-		}
-		p = p[72:]
-		var s *ldMachoSect
-		for i := 0; uint32(i) < c.seg.nsect; i++ {
-			s = &c.seg.sect[i]
-			s.name = cstring(p[0:16])
-			s.segname = cstring(p[16:32])
-			s.addr = e8(p[32:])
-			s.size = e8(p[40:])
-			s.off = e4(p[48:])
-			s.align = e4(p[52:])
-			s.reloff = e4(p[56:])
-			s.nreloc = e4(p[60:])
-			s.flags = e4(p[64:])
-			s.res1 = e4(p[68:])
-			s.res2 = e4(p[72:])
-
-			// p+76 is reserved
-			p = p[80:]
-		}
-
-	case LdMachoCmdSymtab:
-		if sz < 24 {
-			return -1
-		}
-		c.sym.symoff = e4(p[8:])
-		c.sym.nsym = e4(p[12:])
-		c.sym.stroff = e4(p[16:])
-		c.sym.strsize = e4(p[20:])
-
-	case LdMachoCmdDysymtab:
-		if sz < 80 {
-			return -1
-		}
-		c.dsym.ilocalsym = e4(p[8:])
-		c.dsym.nlocalsym = e4(p[12:])
-		c.dsym.iextdefsym = e4(p[16:])
-		c.dsym.nextdefsym = e4(p[20:])
-		c.dsym.iundefsym = e4(p[24:])
-		c.dsym.nundefsym = e4(p[28:])
-		c.dsym.tocoff = e4(p[32:])
-		c.dsym.ntoc = e4(p[36:])
-		c.dsym.modtaboff = e4(p[40:])
-		c.dsym.nmodtab = e4(p[44:])
-		c.dsym.extrefsymoff = e4(p[48:])
-		c.dsym.nextrefsyms = e4(p[52:])
-		c.dsym.indirectsymoff = e4(p[56:])
-		c.dsym.nindirectsyms = e4(p[60:])
-		c.dsym.extreloff = e4(p[64:])
-		c.dsym.nextrel = e4(p[68:])
-		c.dsym.locreloff = e4(p[72:])
-		c.dsym.nlocrel = e4(p[76:])
-	}
-
-	return 0
-}
-
-func macholoadrel(m *ldMachoObj, sect *ldMachoSect) int {
-	if sect.rel != nil || sect.nreloc == 0 {
-		return 0
-	}
-	rel := make([]ldMachoRel, sect.nreloc)
-	n := int(sect.nreloc * 8)
-	buf := make([]byte, n)
-	m.f.MustSeek(m.base+int64(sect.reloff), 0)
-	if _, err := io.ReadFull(m.f, buf); err != nil {
-		return -1
-	}
-	for i := uint32(0); i < sect.nreloc; i++ {
-		r := &rel[i]
-		p := buf[i*8:]
-		r.addr = m.e.Uint32(p)
-
-		// TODO(rsc): Wrong interpretation for big-endian bitfields?
-		if r.addr&0x80000000 != 0 {
-			// scatterbrained relocation
-			r.scattered = 1
-
-			v := r.addr >> 24
-			r.addr &= 0xFFFFFF
-			r.type_ = uint8(v & 0xF)
-			v >>= 4
-			r.length = 1 << (v & 3)
-			v >>= 2
-			r.pcrel = uint8(v & 1)
-			r.value = m.e.Uint32(p[4:])
-		} else {
-			v := m.e.Uint32(p[4:])
-			r.symnum = v & 0xFFFFFF
-			v >>= 24
-			r.pcrel = uint8(v & 1)
-			v >>= 1
-			r.length = 1 << (v & 3)
-			v >>= 2
-			r.extrn = uint8(v & 1)
-			v >>= 1
-			r.type_ = uint8(v)
-		}
-	}
-
-	sect.rel = rel
-	return 0
-}
-
-func macholoaddsym(m *ldMachoObj, d *ldMachoDysymtab) int {
-	n := int(d.nindirectsyms)
-
-	p := make([]byte, n*4)
-	m.f.MustSeek(m.base+int64(d.indirectsymoff), 0)
-	if _, err := io.ReadFull(m.f, p); err != nil {
-		return -1
-	}
-
-	d.indir = make([]uint32, n)
-	for i := 0; i < n; i++ {
-		d.indir[i] = m.e.Uint32(p[4*i:])
-	}
-	return 0
-}
-
-func macholoadsym(m *ldMachoObj, symtab *ldMachoSymtab) int {
-	if symtab.sym != nil {
-		return 0
-	}
-
-	strbuf := make([]byte, symtab.strsize)
-	m.f.MustSeek(m.base+int64(symtab.stroff), 0)
-	if _, err := io.ReadFull(m.f, strbuf); err != nil {
-		return -1
-	}
-
-	symsize := 12
-	if m.is64 {
-		symsize = 16
-	}
-	n := int(symtab.nsym * uint32(symsize))
-	symbuf := make([]byte, n)
-	m.f.MustSeek(m.base+int64(symtab.symoff), 0)
-	if _, err := io.ReadFull(m.f, symbuf); err != nil {
-		return -1
-	}
-	sym := make([]ldMachoSym, symtab.nsym)
-	p := symbuf
-	for i := uint32(0); i < symtab.nsym; i++ {
-		s := &sym[i]
-		v := m.e.Uint32(p)
-		if v >= symtab.strsize {
-			return -1
-		}
-		s.name = cstring(strbuf[v:])
-		s.type_ = p[4]
-		s.sectnum = p[5]
-		s.desc = m.e.Uint16(p[6:])
-		if m.is64 {
-			s.value = m.e.Uint64(p[8:])
-		} else {
-			s.value = uint64(m.e.Uint32(p[8:]))
-		}
-		p = p[symsize:]
-	}
-
-	symtab.str = strbuf
-	symtab.sym = sym
-	return 0
-}
-
-func Load(l *loader.Loader, arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length int64, pn string) ([]*sym.Symbol, error) {
-	newSym := func(name string, version int) *sym.Symbol {
-		return l.LookupOrCreate(name, version, syms)
-	}
-	return load(arch, syms.IncVersion(), newSym, f, pkg, length, pn)
-}
-
-func LoadOld(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, err error) {
-	return load(arch, syms.IncVersion(), syms.Lookup, f, pkg, length, pn)
-}
-
-// load the Mach-O file pn from f.
-// Symbols are written into syms, and a slice of the text symbols is returned.
-func load(arch *sys.Arch, localSymVersion int, lookup func(string, int) *sym.Symbol, f *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, err error) {
-	errorf := func(str string, args ...interface{}) ([]*sym.Symbol, error) {
-		return nil, fmt.Errorf("loadmacho: %v: %v", pn, fmt.Sprintf(str, args...))
-	}
-
-	base := f.Offset()
-
-	var hdr [7 * 4]uint8
-	if _, err := io.ReadFull(f, hdr[:]); err != nil {
-		return errorf("reading hdr: %v", err)
-	}
-
-	var e binary.ByteOrder
-	if binary.BigEndian.Uint32(hdr[:])&^1 == 0xFEEDFACE {
-		e = binary.BigEndian
-	} else if binary.LittleEndian.Uint32(hdr[:])&^1 == 0xFEEDFACE {
-		e = binary.LittleEndian
-	} else {
-		return errorf("bad magic - not mach-o file")
-	}
-
-	is64 := e.Uint32(hdr[:]) == 0xFEEDFACF
-	ncmd := e.Uint32(hdr[4*4:])
-	cmdsz := e.Uint32(hdr[5*4:])
-	if ncmd > 0x10000 || cmdsz >= 0x01000000 {
-		return errorf("implausible mach-o header ncmd=%d cmdsz=%d", ncmd, cmdsz)
-	}
-
-	if is64 {
-		f.MustSeek(4, 1) // skip reserved word in header
-	}
-
-	m := &ldMachoObj{
-		f:          f,
-		e:          e,
-		cputype:    uint(e.Uint32(hdr[1*4:])),
-		subcputype: uint(e.Uint32(hdr[2*4:])),
-		filetype:   e.Uint32(hdr[3*4:]),
-		ncmd:       uint(ncmd),
-		flags:      e.Uint32(hdr[6*4:]),
-		is64:       is64,
-		base:       base,
-		length:     length,
-		name:       pn,
-	}
-
-	switch arch.Family {
-	default:
-		return errorf("mach-o %s unimplemented", arch.Name)
-
-	case sys.AMD64:
-		if e != binary.LittleEndian || m.cputype != LdMachoCpuAmd64 {
-			return errorf("mach-o object but not amd64")
-		}
-	}
-
-	m.cmd = make([]ldMachoCmd, ncmd)
-	cmdp := make([]byte, cmdsz)
-	if _, err := io.ReadFull(f, cmdp); err != nil {
-		return errorf("reading cmds: %v", err)
-	}
-
-	// read and parse load commands
-	var c *ldMachoCmd
-
-	var symtab *ldMachoSymtab
-	var dsymtab *ldMachoDysymtab
-
-	off := uint32(len(hdr))
-	for i := uint32(0); i < ncmd; i++ {
-		ty := e.Uint32(cmdp)
-		sz := e.Uint32(cmdp[4:])
-		m.cmd[i].off = off
-		unpackcmd(cmdp, m, &m.cmd[i], uint(ty), uint(sz))
-		cmdp = cmdp[sz:]
-		off += sz
-		if ty == LdMachoCmdSymtab {
-			if symtab != nil {
-				return errorf("multiple symbol tables")
-			}
-
-			symtab = &m.cmd[i].sym
-			macholoadsym(m, symtab)
-		}
-
-		if ty == LdMachoCmdDysymtab {
-			dsymtab = &m.cmd[i].dsym
-			macholoaddsym(m, dsymtab)
-		}
-
-		if (is64 && ty == LdMachoCmdSegment64) || (!is64 && ty == LdMachoCmdSegment) {
-			if c != nil {
-				return errorf("multiple load commands")
-			}
-
-			c = &m.cmd[i]
-		}
-	}
-
-	// load text and data segments into memory.
-	// they are not as small as the load commands, but we'll need
-	// the memory anyway for the symbol images, so we might
-	// as well use one large chunk.
-	if c == nil {
-		return errorf("no load command")
-	}
-
-	if symtab == nil {
-		// our work is done here - no symbols means nothing can refer to this file
-		return
-	}
-
-	if int64(c.seg.fileoff+c.seg.filesz) >= length {
-		return errorf("load segment out of range")
-	}
-
-	f.MustSeek(m.base+int64(c.seg.fileoff), 0)
-	dat := make([]byte, c.seg.filesz)
-	if _, err := io.ReadFull(f, dat); err != nil {
-		return errorf("cannot load object data: %v", err)
-	}
-
-	for i := uint32(0); i < c.seg.nsect; i++ {
-		sect := &c.seg.sect[i]
-		if sect.segname != "__TEXT" && sect.segname != "__DATA" {
-			continue
-		}
-		if sect.name == "__eh_frame" {
-			continue
-		}
-		name := fmt.Sprintf("%s(%s/%s)", pkg, sect.segname, sect.name)
-		s := lookup(name, localSymVersion)
-		if s.Type != 0 {
-			return errorf("duplicate %s/%s", sect.segname, sect.name)
-		}
-
-		if sect.flags&0xff == 1 { // S_ZEROFILL
-			s.P = make([]byte, sect.size)
-		} else {
-			s.P = dat[sect.addr-c.seg.vmaddr:][:sect.size]
-		}
-		s.Size = int64(len(s.P))
-
-		if sect.segname == "__TEXT" {
-			if sect.name == "__text" {
-				s.Type = sym.STEXT
-			} else {
-				s.Type = sym.SRODATA
-			}
-		} else {
-			if sect.name == "__bss" {
-				s.Type = sym.SNOPTRBSS
-				s.P = s.P[:0]
-			} else {
-				s.Type = sym.SNOPTRDATA
-			}
-		}
-
-		sect.sym = s
-	}
-
-	// enter sub-symbols into symbol table.
-	// have to guess sizes from next symbol.
-	for i := uint32(0); i < symtab.nsym; i++ {
-		machsym := &symtab.sym[i]
-		if machsym.type_&N_STAB != 0 {
-			continue
-		}
-
-		// TODO: check sym->type against outer->type.
-		name := machsym.name
-
-		if name[0] == '_' && name[1] != '\x00' {
-			name = name[1:]
-		}
-		v := 0
-		if machsym.type_&N_EXT == 0 {
-			v = localSymVersion
-		}
-		s := lookup(name, v)
-		if machsym.type_&N_EXT == 0 {
-			s.Attr |= sym.AttrDuplicateOK
-		}
-		if machsym.desc&(N_WEAK_REF|N_WEAK_DEF) != 0 {
-			s.Attr |= sym.AttrDuplicateOK
-		}
-		machsym.sym = s
-		if machsym.sectnum == 0 { // undefined
-			continue
-		}
-		if uint32(machsym.sectnum) > c.seg.nsect {
-			return errorf("reference to invalid section %d", machsym.sectnum)
-		}
-
-		sect := &c.seg.sect[machsym.sectnum-1]
-		outer := sect.sym
-		if outer == nil {
-			continue // ignore reference to invalid section
-		}
-
-		if s.Outer != nil {
-			if s.Attr.DuplicateOK() {
-				continue
-			}
-			return errorf("duplicate symbol reference: %s in both %s and %s", s.Name, s.Outer.Name, sect.sym.Name)
-		}
-
-		s.Type = outer.Type
-		s.Attr |= sym.AttrSubSymbol
-		s.Sub = outer.Sub
-		outer.Sub = s
-		s.Outer = outer
-		s.Value = int64(machsym.value - sect.addr)
-		if !s.Attr.CgoExportDynamic() {
-			s.SetDynimplib("") // satisfy dynimport
-		}
-		if outer.Type == sym.STEXT {
-			if s.Attr.External() && !s.Attr.DuplicateOK() {
-				return errorf("%v: duplicate symbol definition", s)
-			}
-			s.Attr |= sym.AttrExternal
-		}
-
-		machsym.sym = s
-	}
-
-	// Sort outer lists by address, adding to textp.
-	// This keeps textp in increasing address order.
-	for i := 0; uint32(i) < c.seg.nsect; i++ {
-		sect := &c.seg.sect[i]
-		s := sect.sym
-		if s == nil {
-			continue
-		}
-		if s.Sub != nil {
-			s.Sub = sym.SortSub(s.Sub)
-
-			// assign sizes, now that we know symbols in sorted order.
-			for s1 := s.Sub; s1 != nil; s1 = s1.Sub {
-				if s1.Sub != nil {
-					s1.Size = s1.Sub.Value - s1.Value
-				} else {
-					s1.Size = s.Value + s.Size - s1.Value
-				}
-			}
-		}
-
-		if s.Type == sym.STEXT {
-			if s.Attr.OnList() {
-				return errorf("symbol %s listed multiple times", s.Name)
-			}
-			s.Attr |= sym.AttrOnList
-			textp = append(textp, s)
-			for s1 := s.Sub; s1 != nil; s1 = s1.Sub {
-				if s1.Attr.OnList() {
-					return errorf("symbol %s listed multiple times", s1.Name)
-				}
-				s1.Attr |= sym.AttrOnList
-				textp = append(textp, s1)
-			}
-		}
-	}
-
-	// load relocations
-	for i := 0; uint32(i) < c.seg.nsect; i++ {
-		sect := &c.seg.sect[i]
-		s := sect.sym
-		if s == nil {
-			continue
-		}
-		macholoadrel(m, sect)
-		if sect.rel == nil {
-			continue
-		}
-		r := make([]sym.Reloc, sect.nreloc)
-		rpi := 0
-		for j := uint32(0); j < sect.nreloc; j++ {
-			rp := &r[rpi]
-			rel := &sect.rel[j]
-			if rel.scattered != 0 {
-				// mach-o only uses scattered relocation on 32-bit platforms,
-				// which are no longer supported.
-				return errorf("%v: unexpected scattered relocation", s)
-			}
-
-			rp.Siz = rel.length
-			rp.Type = objabi.MachoRelocOffset + (objabi.RelocType(rel.type_) << 1) + objabi.RelocType(rel.pcrel)
-			rp.Off = int32(rel.addr)
-
-			// Handle X86_64_RELOC_SIGNED referencing a section (rel->extrn == 0).
-			if arch.Family == sys.AMD64 && rel.extrn == 0 && rel.type_ == MACHO_X86_64_RELOC_SIGNED {
-				// Calculate the addend as the offset into the section.
-				//
-				// The rip-relative offset stored in the object file is encoded
-				// as follows:
-				//
-				//    movsd	0x00000360(%rip),%xmm0
-				//
-				// To get the absolute address of the value this rip-relative address is pointing
-				// to, we must add the address of the next instruction to it. This is done by
-				// taking the address of the relocation and adding 4 to it (since the rip-relative
-				// offset can at most be 32 bits long).  To calculate the offset into the section the
-				// relocation is referencing, we subtract the vaddr of the start of the referenced
-				// section found in the original object file.
-				//
-				// [For future reference, see Darwin's /usr/include/mach-o/x86_64/reloc.h]
-				secaddr := c.seg.sect[rel.symnum-1].addr
-
-				rp.Add = int64(uint64(int64(int32(e.Uint32(s.P[rp.Off:])))+int64(rp.Off)+4) - secaddr)
-			} else {
-				rp.Add = int64(int32(e.Uint32(s.P[rp.Off:])))
-			}
-
-			// An unsigned internal relocation has a value offset
-			// by the section address.
-			if arch.Family == sys.AMD64 && rel.extrn == 0 && rel.type_ == MACHO_X86_64_RELOC_UNSIGNED {
-				secaddr := c.seg.sect[rel.symnum-1].addr
-				rp.Add -= int64(secaddr)
-			}
-
-			if rel.extrn == 0 {
-				if rel.symnum < 1 || rel.symnum > c.seg.nsect {
-					return errorf("invalid relocation: section reference out of range %d vs %d", rel.symnum, c.seg.nsect)
-				}
-
-				rp.Sym = c.seg.sect[rel.symnum-1].sym
-				if rp.Sym == nil {
-					return errorf("invalid relocation: %s", c.seg.sect[rel.symnum-1].name)
-				}
-			} else {
-				if rel.symnum >= symtab.nsym {
-					return errorf("invalid relocation: symbol reference out of range")
-				}
-
-				rp.Sym = symtab.sym[rel.symnum].sym
-			}
-
-			rpi++
-		}
-
-		sort.Sort(sym.RelocByOff(r[:rpi]))
-		s.R = r
-		s.R = s.R[:rpi]
-	}
-
-	return textp, nil
-}
-
-func cstring(x []byte) string {
-	i := bytes.IndexByte(x, '\x00')
-	if i >= 0 {
-		x = x[:i]
-	}
-	return string(x)
-}
diff --git a/src/cmd/oldlink/internal/loadpe/ldpe.go b/src/cmd/oldlink/internal/loadpe/ldpe.go
deleted file mode 100644
index f7df774..0000000
--- a/src/cmd/oldlink/internal/loadpe/ldpe.go
+++ /dev/null
@@ -1,513 +0,0 @@
-// 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 loadpe implements a PE/COFF file reader.
-package loadpe
-
-import (
-	"cmd/internal/bio"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/loader"
-	"cmd/oldlink/internal/sym"
-	"debug/pe"
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"io"
-	"sort"
-	"strings"
-)
-
-const (
-	// TODO: the Microsoft doco says IMAGE_SYM_DTYPE_ARRAY is 3 (same with IMAGE_SYM_DTYPE_POINTER and IMAGE_SYM_DTYPE_FUNCTION)
-	IMAGE_SYM_UNDEFINED              = 0
-	IMAGE_SYM_ABSOLUTE               = -1
-	IMAGE_SYM_DEBUG                  = -2
-	IMAGE_SYM_TYPE_NULL              = 0
-	IMAGE_SYM_TYPE_VOID              = 1
-	IMAGE_SYM_TYPE_CHAR              = 2
-	IMAGE_SYM_TYPE_SHORT             = 3
-	IMAGE_SYM_TYPE_INT               = 4
-	IMAGE_SYM_TYPE_LONG              = 5
-	IMAGE_SYM_TYPE_FLOAT             = 6
-	IMAGE_SYM_TYPE_DOUBLE            = 7
-	IMAGE_SYM_TYPE_STRUCT            = 8
-	IMAGE_SYM_TYPE_UNION             = 9
-	IMAGE_SYM_TYPE_ENUM              = 10
-	IMAGE_SYM_TYPE_MOE               = 11
-	IMAGE_SYM_TYPE_BYTE              = 12
-	IMAGE_SYM_TYPE_WORD              = 13
-	IMAGE_SYM_TYPE_UINT              = 14
-	IMAGE_SYM_TYPE_DWORD             = 15
-	IMAGE_SYM_TYPE_PCODE             = 32768
-	IMAGE_SYM_DTYPE_NULL             = 0
-	IMAGE_SYM_DTYPE_POINTER          = 0x10
-	IMAGE_SYM_DTYPE_FUNCTION         = 0x20
-	IMAGE_SYM_DTYPE_ARRAY            = 0x30
-	IMAGE_SYM_CLASS_END_OF_FUNCTION  = -1
-	IMAGE_SYM_CLASS_NULL             = 0
-	IMAGE_SYM_CLASS_AUTOMATIC        = 1
-	IMAGE_SYM_CLASS_EXTERNAL         = 2
-	IMAGE_SYM_CLASS_STATIC           = 3
-	IMAGE_SYM_CLASS_REGISTER         = 4
-	IMAGE_SYM_CLASS_EXTERNAL_DEF     = 5
-	IMAGE_SYM_CLASS_LABEL            = 6
-	IMAGE_SYM_CLASS_UNDEFINED_LABEL  = 7
-	IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8
-	IMAGE_SYM_CLASS_ARGUMENT         = 9
-	IMAGE_SYM_CLASS_STRUCT_TAG       = 10
-	IMAGE_SYM_CLASS_MEMBER_OF_UNION  = 11
-	IMAGE_SYM_CLASS_UNION_TAG        = 12
-	IMAGE_SYM_CLASS_TYPE_DEFINITION  = 13
-	IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14
-	IMAGE_SYM_CLASS_ENUM_TAG         = 15
-	IMAGE_SYM_CLASS_MEMBER_OF_ENUM   = 16
-	IMAGE_SYM_CLASS_REGISTER_PARAM   = 17
-	IMAGE_SYM_CLASS_BIT_FIELD        = 18
-	IMAGE_SYM_CLASS_FAR_EXTERNAL     = 68 /* Not in PECOFF v8 spec */
-	IMAGE_SYM_CLASS_BLOCK            = 100
-	IMAGE_SYM_CLASS_FUNCTION         = 101
-	IMAGE_SYM_CLASS_END_OF_STRUCT    = 102
-	IMAGE_SYM_CLASS_FILE             = 103
-	IMAGE_SYM_CLASS_SECTION          = 104
-	IMAGE_SYM_CLASS_WEAK_EXTERNAL    = 105
-	IMAGE_SYM_CLASS_CLR_TOKEN        = 107
-	IMAGE_REL_I386_ABSOLUTE          = 0x0000
-	IMAGE_REL_I386_DIR16             = 0x0001
-	IMAGE_REL_I386_REL16             = 0x0002
-	IMAGE_REL_I386_DIR32             = 0x0006
-	IMAGE_REL_I386_DIR32NB           = 0x0007
-	IMAGE_REL_I386_SEG12             = 0x0009
-	IMAGE_REL_I386_SECTION           = 0x000A
-	IMAGE_REL_I386_SECREL            = 0x000B
-	IMAGE_REL_I386_TOKEN             = 0x000C
-	IMAGE_REL_I386_SECREL7           = 0x000D
-	IMAGE_REL_I386_REL32             = 0x0014
-	IMAGE_REL_AMD64_ABSOLUTE         = 0x0000
-	IMAGE_REL_AMD64_ADDR64           = 0x0001
-	IMAGE_REL_AMD64_ADDR32           = 0x0002
-	IMAGE_REL_AMD64_ADDR32NB         = 0x0003
-	IMAGE_REL_AMD64_REL32            = 0x0004
-	IMAGE_REL_AMD64_REL32_1          = 0x0005
-	IMAGE_REL_AMD64_REL32_2          = 0x0006
-	IMAGE_REL_AMD64_REL32_3          = 0x0007
-	IMAGE_REL_AMD64_REL32_4          = 0x0008
-	IMAGE_REL_AMD64_REL32_5          = 0x0009
-	IMAGE_REL_AMD64_SECTION          = 0x000A
-	IMAGE_REL_AMD64_SECREL           = 0x000B
-	IMAGE_REL_AMD64_SECREL7          = 0x000C
-	IMAGE_REL_AMD64_TOKEN            = 0x000D
-	IMAGE_REL_AMD64_SREL32           = 0x000E
-	IMAGE_REL_AMD64_PAIR             = 0x000F
-	IMAGE_REL_AMD64_SSPAN32          = 0x0010
-	IMAGE_REL_ARM_ABSOLUTE           = 0x0000
-	IMAGE_REL_ARM_ADDR32             = 0x0001
-	IMAGE_REL_ARM_ADDR32NB           = 0x0002
-	IMAGE_REL_ARM_BRANCH24           = 0x0003
-	IMAGE_REL_ARM_BRANCH11           = 0x0004
-	IMAGE_REL_ARM_SECTION            = 0x000E
-	IMAGE_REL_ARM_SECREL             = 0x000F
-	IMAGE_REL_ARM_MOV32              = 0x0010
-	IMAGE_REL_THUMB_MOV32            = 0x0011
-	IMAGE_REL_THUMB_BRANCH20         = 0x0012
-	IMAGE_REL_THUMB_BRANCH24         = 0x0014
-	IMAGE_REL_THUMB_BLX23            = 0x0015
-	IMAGE_REL_ARM_PAIR               = 0x0016
-)
-
-// TODO(crawshaw): de-duplicate these symbols with cmd/internal/ld, ideally in debug/pe.
-const (
-	IMAGE_SCN_CNT_CODE               = 0x00000020
-	IMAGE_SCN_CNT_INITIALIZED_DATA   = 0x00000040
-	IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080
-	IMAGE_SCN_MEM_DISCARDABLE        = 0x02000000
-	IMAGE_SCN_MEM_EXECUTE            = 0x20000000
-	IMAGE_SCN_MEM_READ               = 0x40000000
-	IMAGE_SCN_MEM_WRITE              = 0x80000000
-)
-
-// TODO(brainman): maybe just add ReadAt method to bio.Reader instead of creating peBiobuf
-
-// peBiobuf makes bio.Reader look like io.ReaderAt.
-type peBiobuf bio.Reader
-
-func (f *peBiobuf) ReadAt(p []byte, off int64) (int, error) {
-	ret := ((*bio.Reader)(f)).MustSeek(off, 0)
-	if ret < 0 {
-		return 0, errors.New("fail to seek")
-	}
-	n, err := f.Read(p)
-	if err != nil {
-		return 0, err
-	}
-	return n, nil
-}
-
-func Load(l *loader.Loader, arch *sys.Arch, syms *sym.Symbols, input *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, rsrc *sym.Symbol, err error) {
-	lookup := func(name string, version int) *sym.Symbol {
-		return l.LookupOrCreate(name, version, syms)
-	}
-	return load(arch, lookup, syms.IncVersion(), input, pkg, length, pn)
-}
-
-func LoadOld(arch *sys.Arch, syms *sym.Symbols, input *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, rsrc *sym.Symbol, err error) {
-	return load(arch, syms.Lookup, syms.IncVersion(), input, pkg, length, pn)
-}
-
-// load loads the PE file pn from input.
-// Symbols are written into syms, and a slice of the text symbols is returned.
-// If an .rsrc section is found, its symbol is returned as rsrc.
-func load(arch *sys.Arch, lookup func(string, int) *sym.Symbol, localSymVersion int, input *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, rsrc *sym.Symbol, err error) {
-	sectsyms := make(map[*pe.Section]*sym.Symbol)
-	sectdata := make(map[*pe.Section][]byte)
-
-	// Some input files are archives containing multiple of
-	// object files, and pe.NewFile seeks to the start of
-	// input file and get confused. Create section reader
-	// to stop pe.NewFile looking before current position.
-	sr := io.NewSectionReader((*peBiobuf)(input), input.Offset(), 1<<63-1)
-
-	// TODO: replace pe.NewFile with pe.Load (grep for "add Load function" in debug/pe for details)
-	f, err := pe.NewFile(sr)
-	if err != nil {
-		return nil, nil, err
-	}
-	defer f.Close()
-
-	// TODO return error if found .cormeta
-
-	// create symbols for mapped sections
-	for _, sect := range f.Sections {
-		if sect.Characteristics&IMAGE_SCN_MEM_DISCARDABLE != 0 {
-			continue
-		}
-
-		if sect.Characteristics&(IMAGE_SCN_CNT_CODE|IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0 {
-			// This has been seen for .idata sections, which we
-			// want to ignore. See issues 5106 and 5273.
-			continue
-		}
-
-		name := fmt.Sprintf("%s(%s)", pkg, sect.Name)
-		s := lookup(name, localSymVersion)
-
-		switch sect.Characteristics & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE) {
-		case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ: //.rdata
-			s.Type = sym.SRODATA
-
-		case IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE: //.bss
-			s.Type = sym.SNOPTRBSS
-
-		case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE: //.data
-			s.Type = sym.SNOPTRDATA
-
-		case IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ: //.text
-			s.Type = sym.STEXT
-
-		default:
-			return nil, nil, fmt.Errorf("unexpected flags %#06x for PE section %s", sect.Characteristics, sect.Name)
-		}
-
-		if s.Type != sym.SNOPTRBSS {
-			data, err := sect.Data()
-			if err != nil {
-				return nil, nil, err
-			}
-			sectdata[sect] = data
-			s.P = data
-		}
-		s.Size = int64(sect.Size)
-		sectsyms[sect] = s
-		if sect.Name == ".rsrc" {
-			rsrc = s
-		}
-	}
-
-	// load relocations
-	for _, rsect := range f.Sections {
-		if _, found := sectsyms[rsect]; !found {
-			continue
-		}
-		if rsect.NumberOfRelocations == 0 {
-			continue
-		}
-		if rsect.Characteristics&IMAGE_SCN_MEM_DISCARDABLE != 0 {
-			continue
-		}
-		if rsect.Characteristics&(IMAGE_SCN_CNT_CODE|IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0 {
-			// This has been seen for .idata sections, which we
-			// want to ignore. See issues 5106 and 5273.
-			continue
-		}
-
-		rs := make([]sym.Reloc, rsect.NumberOfRelocations)
-		for j, r := range rsect.Relocs {
-			rp := &rs[j]
-			if int(r.SymbolTableIndex) >= len(f.COFFSymbols) {
-				return nil, nil, fmt.Errorf("relocation number %d symbol index idx=%d cannot be large then number of symbols %d", j, r.SymbolTableIndex, len(f.COFFSymbols))
-			}
-			pesym := &f.COFFSymbols[r.SymbolTableIndex]
-			gosym, err := readpesym(arch, lookup, f, pesym, sectsyms, localSymVersion)
-			if err != nil {
-				return nil, nil, err
-			}
-			if gosym == nil {
-				name, err := pesym.FullName(f.StringTable)
-				if err != nil {
-					name = string(pesym.Name[:])
-				}
-				return nil, nil, fmt.Errorf("reloc of invalid sym %s idx=%d type=%d", name, r.SymbolTableIndex, pesym.Type)
-			}
-
-			rp.Sym = gosym
-			rp.Siz = 4
-			rp.Off = int32(r.VirtualAddress)
-			switch arch.Family {
-			default:
-				return nil, nil, fmt.Errorf("%s: unsupported arch %v", pn, arch.Family)
-			case sys.I386, sys.AMD64:
-				switch r.Type {
-				default:
-					return nil, nil, fmt.Errorf("%s: %v: unknown relocation type %v", pn, sectsyms[rsect], r.Type)
-
-				case IMAGE_REL_I386_REL32, IMAGE_REL_AMD64_REL32,
-					IMAGE_REL_AMD64_ADDR32, // R_X86_64_PC32
-					IMAGE_REL_AMD64_ADDR32NB:
-					rp.Type = objabi.R_PCREL
-
-					rp.Add = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rp.Off:])))
-
-				case IMAGE_REL_I386_DIR32NB, IMAGE_REL_I386_DIR32:
-					rp.Type = objabi.R_ADDR
-
-					// load addend from image
-					rp.Add = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rp.Off:])))
-
-				case IMAGE_REL_AMD64_ADDR64: // R_X86_64_64
-					rp.Siz = 8
-
-					rp.Type = objabi.R_ADDR
-
-					// load addend from image
-					rp.Add = int64(binary.LittleEndian.Uint64(sectdata[rsect][rp.Off:]))
-				}
-
-			case sys.ARM:
-				switch r.Type {
-				default:
-					return nil, nil, fmt.Errorf("%s: %v: unknown ARM relocation type %v", pn, sectsyms[rsect], r.Type)
-
-				case IMAGE_REL_ARM_SECREL:
-					rp.Type = objabi.R_PCREL
-
-					rp.Add = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rp.Off:])))
-
-				case IMAGE_REL_ARM_ADDR32:
-					rp.Type = objabi.R_ADDR
-
-					rp.Add = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rp.Off:])))
-
-				case IMAGE_REL_ARM_BRANCH24:
-					rp.Type = objabi.R_CALLARM
-
-					rp.Add = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rp.Off:])))
-				}
-			}
-
-			// ld -r could generate multiple section symbols for the
-			// same section but with different values, we have to take
-			// that into account
-			if issect(pesym) {
-				rp.Add += int64(pesym.Value)
-			}
-		}
-
-		sort.Sort(sym.RelocByOff(rs[:rsect.NumberOfRelocations]))
-
-		s := sectsyms[rsect]
-		s.R = rs
-		s.R = s.R[:rsect.NumberOfRelocations]
-	}
-
-	// enter sub-symbols into symbol table.
-	for i, numaux := 0, 0; i < len(f.COFFSymbols); i += numaux + 1 {
-		pesym := &f.COFFSymbols[i]
-
-		numaux = int(pesym.NumberOfAuxSymbols)
-
-		name, err := pesym.FullName(f.StringTable)
-		if err != nil {
-			return nil, nil, err
-		}
-		if name == "" {
-			continue
-		}
-		if issect(pesym) {
-			continue
-		}
-		if int(pesym.SectionNumber) > len(f.Sections) {
-			continue
-		}
-		if pesym.SectionNumber == IMAGE_SYM_DEBUG {
-			continue
-		}
-		var sect *pe.Section
-		if pesym.SectionNumber > 0 {
-			sect = f.Sections[pesym.SectionNumber-1]
-			if _, found := sectsyms[sect]; !found {
-				continue
-			}
-		}
-
-		s, err := readpesym(arch, lookup, f, pesym, sectsyms, localSymVersion)
-		if err != nil {
-			return nil, nil, err
-		}
-
-		if pesym.SectionNumber == 0 { // extern
-			if s.Type == sym.SDYNIMPORT {
-				s.SetPlt(-2) // flag for dynimport in PE object files.
-			}
-			if s.Type == sym.SXREF && pesym.Value > 0 { // global data
-				s.Type = sym.SNOPTRDATA
-				s.Size = int64(pesym.Value)
-			}
-
-			continue
-		} else if pesym.SectionNumber > 0 && int(pesym.SectionNumber) <= len(f.Sections) {
-			sect = f.Sections[pesym.SectionNumber-1]
-			if _, found := sectsyms[sect]; !found {
-				return nil, nil, fmt.Errorf("%s: %v: missing sect.sym", pn, s)
-			}
-		} else {
-			return nil, nil, fmt.Errorf("%s: %v: sectnum < 0!", pn, s)
-		}
-
-		if sect == nil {
-			return nil, rsrc, nil
-		}
-
-		if s.Outer != nil {
-			if s.Attr.DuplicateOK() {
-				continue
-			}
-			return nil, nil, fmt.Errorf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sectsyms[sect].Name)
-		}
-
-		sectsym := sectsyms[sect]
-		s.Sub = sectsym.Sub
-		sectsym.Sub = s
-		s.Type = sectsym.Type
-		s.Attr |= sym.AttrSubSymbol
-		s.Value = int64(pesym.Value)
-		s.Size = 4
-		s.Outer = sectsym
-		if sectsym.Type == sym.STEXT {
-			if s.Attr.External() && !s.Attr.DuplicateOK() {
-				return nil, nil, fmt.Errorf("%s: duplicate symbol definition", s.Name)
-			}
-			s.Attr |= sym.AttrExternal
-		}
-	}
-
-	// Sort outer lists by address, adding to textp.
-	// This keeps textp in increasing address order.
-	for _, sect := range f.Sections {
-		s := sectsyms[sect]
-		if s == nil {
-			continue
-		}
-		if s.Sub != nil {
-			s.Sub = sym.SortSub(s.Sub)
-		}
-		if s.Type == sym.STEXT {
-			if s.Attr.OnList() {
-				return nil, nil, fmt.Errorf("symbol %s listed multiple times", s.Name)
-			}
-			s.Attr |= sym.AttrOnList
-			textp = append(textp, s)
-			for s = s.Sub; s != nil; s = s.Sub {
-				if s.Attr.OnList() {
-					return nil, nil, fmt.Errorf("symbol %s listed multiple times", s.Name)
-				}
-				s.Attr |= sym.AttrOnList
-				textp = append(textp, s)
-			}
-		}
-	}
-
-	return textp, rsrc, nil
-}
-
-func issect(s *pe.COFFSymbol) bool {
-	return s.StorageClass == IMAGE_SYM_CLASS_STATIC && s.Type == 0 && s.Name[0] == '.'
-}
-
-func readpesym(arch *sys.Arch, lookup func(string, int) *sym.Symbol, f *pe.File, pesym *pe.COFFSymbol, sectsyms map[*pe.Section]*sym.Symbol, localSymVersion int) (*sym.Symbol, error) {
-	symname, err := pesym.FullName(f.StringTable)
-	if err != nil {
-		return nil, err
-	}
-	var name string
-	if issect(pesym) {
-		name = sectsyms[f.Sections[pesym.SectionNumber-1]].Name
-	} else {
-		name = symname
-		switch arch.Family {
-		case sys.AMD64:
-			if name == "__imp___acrt_iob_func" {
-				// Do not rename __imp___acrt_iob_func into __acrt_iob_func,
-				// because __imp___acrt_iob_func symbol is real
-				// (see commit b295099 from git://git.code.sf.net/p/mingw-w64/mingw-w64 for details).
-			} else {
-				name = strings.TrimPrefix(name, "__imp_") // __imp_Name => Name
-			}
-		case sys.I386:
-			if name == "__imp____acrt_iob_func" {
-				// Do not rename __imp____acrt_iob_func into ___acrt_iob_func,
-				// because __imp____acrt_iob_func symbol is real
-				// (see commit b295099 from git://git.code.sf.net/p/mingw-w64/mingw-w64 for details).
-			} else {
-				name = strings.TrimPrefix(name, "__imp_") // __imp_Name => Name
-			}
-			if name[0] == '_' {
-				name = name[1:] // _Name => Name
-			}
-		}
-	}
-
-	// remove last @XXX
-	if i := strings.LastIndex(name, "@"); i >= 0 {
-		name = name[:i]
-	}
-
-	var s *sym.Symbol
-	switch pesym.Type {
-	default:
-		return nil, fmt.Errorf("%s: invalid symbol type %d", symname, pesym.Type)
-
-	case IMAGE_SYM_DTYPE_FUNCTION, IMAGE_SYM_DTYPE_NULL:
-		switch pesym.StorageClass {
-		case IMAGE_SYM_CLASS_EXTERNAL: //global
-			s = lookup(name, 0)
-
-		case IMAGE_SYM_CLASS_NULL, IMAGE_SYM_CLASS_STATIC, IMAGE_SYM_CLASS_LABEL:
-			s = lookup(name, localSymVersion)
-			s.Attr |= sym.AttrDuplicateOK
-
-		default:
-			return nil, fmt.Errorf("%s: invalid symbol binding %d", symname, pesym.StorageClass)
-		}
-	}
-
-	if s != nil && s.Type == 0 && (pesym.StorageClass != IMAGE_SYM_CLASS_STATIC || pesym.Value != 0) {
-		s.Type = sym.SXREF
-	}
-	if strings.HasPrefix(symname, "__imp_") {
-		s.SetGot(-2) // flag for __imp_
-	}
-
-	return s, nil
-}
diff --git a/src/cmd/oldlink/internal/loadxcoff/ldxcoff.go b/src/cmd/oldlink/internal/loadxcoff/ldxcoff.go
deleted file mode 100644
index 832b168..0000000
--- a/src/cmd/oldlink/internal/loadxcoff/ldxcoff.go
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright 2018 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 loadxcoff implements a XCOFF file reader.
-package loadxcoff
-
-import (
-	"cmd/internal/bio"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/loader"
-	"cmd/oldlink/internal/sym"
-	"errors"
-	"fmt"
-	"internal/xcoff"
-)
-
-// ldSection is an XCOFF section with its symbols.
-type ldSection struct {
-	xcoff.Section
-	sym *sym.Symbol
-}
-
-// TODO(brainman): maybe just add ReadAt method to bio.Reader instead of creating xcoffBiobuf
-
-// xcoffBiobuf makes bio.Reader look like io.ReaderAt.
-type xcoffBiobuf bio.Reader
-
-func (f *xcoffBiobuf) ReadAt(p []byte, off int64) (int, error) {
-	ret := ((*bio.Reader)(f)).MustSeek(off, 0)
-	if ret < 0 {
-		return 0, errors.New("fail to seek")
-	}
-	n, err := f.Read(p)
-	if err != nil {
-		return 0, err
-	}
-	return n, nil
-}
-
-// Load loads xcoff files with the indexed object files.
-func Load(l *loader.Loader, arch *sys.Arch, syms *sym.Symbols, input *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, err error) {
-	lookup := func(name string, version int) *sym.Symbol {
-		return l.LookupOrCreate(name, version, syms)
-	}
-	return load(arch, lookup, syms.IncVersion(), input, pkg, length, pn)
-}
-
-// LoadOld uses the old version of object loading.
-func LoadOld(arch *sys.Arch, syms *sym.Symbols, input *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, err error) {
-	return load(arch, syms.Lookup, syms.IncVersion(), input, pkg, length, pn)
-}
-
-// loads the Xcoff file pn from f.
-// Symbols are written into syms, and a slice of the text symbols is returned.
-func load(arch *sys.Arch, lookup func(string, int) *sym.Symbol, localSymVersion int, input *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, err error) {
-	errorf := func(str string, args ...interface{}) ([]*sym.Symbol, error) {
-		return nil, fmt.Errorf("loadxcoff: %v: %v", pn, fmt.Sprintf(str, args...))
-	}
-
-	var ldSections []*ldSection
-
-	f, err := xcoff.NewFile((*xcoffBiobuf)(input))
-	if err != nil {
-		return nil, err
-	}
-	defer f.Close()
-
-	for _, sect := range f.Sections {
-		//only text, data and bss section
-		if sect.Type < xcoff.STYP_TEXT || sect.Type > xcoff.STYP_BSS {
-			continue
-		}
-		lds := new(ldSection)
-		lds.Section = *sect
-		name := fmt.Sprintf("%s(%s)", pkg, lds.Name)
-		s := lookup(name, localSymVersion)
-
-		switch lds.Type {
-		default:
-			return errorf("unrecognized section type 0x%x", lds.Type)
-		case xcoff.STYP_TEXT:
-			s.Type = sym.STEXT
-		case xcoff.STYP_DATA:
-			s.Type = sym.SNOPTRDATA
-		case xcoff.STYP_BSS:
-			s.Type = sym.SNOPTRBSS
-		}
-
-		s.Size = int64(lds.Size)
-		if s.Type != sym.SNOPTRBSS {
-			data, err := lds.Section.Data()
-			if err != nil {
-				return nil, err
-			}
-			s.P = data
-		}
-
-		lds.sym = s
-		ldSections = append(ldSections, lds)
-	}
-
-	// sx = symbol from file
-	// s = symbol for syms
-	for _, sx := range f.Symbols {
-		// get symbol type
-		stype, errmsg := getSymbolType(f, sx)
-		if errmsg != "" {
-			return errorf("error reading symbol %s: %s", sx.Name, errmsg)
-		}
-		if stype == sym.Sxxx {
-			continue
-		}
-
-		s := lookup(sx.Name, 0)
-
-		// Text symbol
-		if s.Type == sym.STEXT {
-			if s.Attr.OnList() {
-				return errorf("symbol %s listed multiple times", s.Name)
-			}
-			s.Attr |= sym.AttrOnList
-			textp = append(textp, s)
-		}
-	}
-
-	// Read relocations
-	for _, sect := range ldSections {
-		// TODO(aix): Dwarf section relocation if needed
-		if sect.Type != xcoff.STYP_TEXT && sect.Type != xcoff.STYP_DATA {
-			continue
-		}
-		rs := make([]sym.Reloc, sect.Nreloc)
-		for i, rx := range sect.Relocs {
-			r := &rs[i]
-
-			r.Sym = lookup(rx.Symbol.Name, 0)
-			if uint64(int32(rx.VirtualAddress)) != rx.VirtualAddress {
-				return errorf("virtual address of a relocation is too big: 0x%x", rx.VirtualAddress)
-			}
-			r.Off = int32(rx.VirtualAddress)
-			switch rx.Type {
-			default:
-				return errorf("section %s: unknown relocation of type 0x%x", sect.Name, rx.Type)
-			case xcoff.R_POS:
-				// Reloc the address of r.Sym
-				// Length should be 64
-				if rx.Length != 64 {
-					return errorf("section %s: relocation R_POS has length different from 64: %d", sect.Name, rx.Length)
-				}
-				r.Siz = 8
-				r.Type = objabi.R_CONST
-				r.Add = int64(rx.Symbol.Value)
-
-			case xcoff.R_RBR:
-				r.Siz = 4
-				r.Type = objabi.R_CALLPOWER
-				r.Add = 0 //
-
-			}
-		}
-		s := sect.sym
-		s.R = rs
-		s.R = s.R[:sect.Nreloc]
-	}
-	return textp, nil
-
-}
-
-// Convert symbol xcoff type to sym.SymKind
-// Returns nil if this shouldn't be added into syms (like .file or .dw symbols )
-func getSymbolType(f *xcoff.File, s *xcoff.Symbol) (stype sym.SymKind, err string) {
-	// .file symbol
-	if s.SectionNumber == -2 {
-		if s.StorageClass == xcoff.C_FILE {
-			return sym.Sxxx, ""
-		}
-		return sym.Sxxx, "unrecognised StorageClass for sectionNumber = -2"
-	}
-
-	// extern symbols
-	// TODO(aix)
-	if s.SectionNumber == 0 {
-		return sym.Sxxx, ""
-	}
-
-	sectType := f.Sections[s.SectionNumber-1].SectionHeader.Type
-	switch sectType {
-	default:
-		return sym.Sxxx, fmt.Sprintf("getSymbolType for Section type 0x%x not implemented", sectType)
-	case xcoff.STYP_DWARF, xcoff.STYP_DEBUG:
-		return sym.Sxxx, ""
-	case xcoff.STYP_DATA, xcoff.STYP_BSS, xcoff.STYP_TEXT:
-	}
-
-	switch s.StorageClass {
-	default:
-		return sym.Sxxx, fmt.Sprintf("getSymbolType for Storage class 0x%x not implemented", s.StorageClass)
-	case xcoff.C_HIDEXT, xcoff.C_EXT, xcoff.C_WEAKEXT:
-		switch s.AuxCSect.StorageMappingClass {
-		default:
-			return sym.Sxxx, fmt.Sprintf("getSymbolType for Storage class 0x%x and Storage Map 0x%x not implemented", s.StorageClass, s.AuxCSect.StorageMappingClass)
-
-		// Program Code
-		case xcoff.XMC_PR:
-			if sectType == xcoff.STYP_TEXT {
-				return sym.STEXT, ""
-			}
-			return sym.Sxxx, fmt.Sprintf("unrecognised Section Type 0x%x for Storage Class 0x%x with Storage Map XMC_PR", sectType, s.StorageClass)
-
-		// Read/Write Data
-		case xcoff.XMC_RW:
-			if sectType == xcoff.STYP_DATA {
-				return sym.SDATA, ""
-			}
-			if sectType == xcoff.STYP_BSS {
-				return sym.SBSS, ""
-			}
-			return sym.Sxxx, fmt.Sprintf("unrecognised Section Type 0x%x for Storage Class 0x%x with Storage Map XMC_RW", sectType, s.StorageClass)
-
-		// Function descriptor
-		case xcoff.XMC_DS:
-			if sectType == xcoff.STYP_DATA {
-				return sym.SDATA, ""
-			}
-			return sym.Sxxx, fmt.Sprintf("unrecognised Section Type 0x%x for Storage Class 0x%x with Storage Map XMC_DS", sectType, s.StorageClass)
-
-		// TOC anchor and TOC entry
-		case xcoff.XMC_TC0, xcoff.XMC_TE:
-			if sectType == xcoff.STYP_DATA {
-				return sym.SXCOFFTOC, ""
-			}
-			return sym.Sxxx, fmt.Sprintf("unrecognised Section Type 0x%x for Storage Class 0x%x with Storage Map XMC_DS", sectType, s.StorageClass)
-
-		}
-	}
-}
diff --git a/src/cmd/oldlink/internal/mips/asm.go b/src/cmd/oldlink/internal/mips/asm.go
deleted file mode 100644
index 48a2324..0000000
--- a/src/cmd/oldlink/internal/mips/asm.go
+++ /dev/null
@@ -1,230 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2016 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package mips
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-	"cmd/oldlink/internal/sym"
-	"debug/elf"
-	"fmt"
-	"log"
-)
-
-func gentext(ctxt *ld.Link) {
-	return
-}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-	log.Fatalf("adddynrel not implemented")
-	return false
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-	ctxt.Out.Write32(uint32(sectoff))
-
-	elfsym := r.Xsym.ElfsymForReloc()
-	switch r.Type {
-	default:
-		return false
-	case objabi.R_ADDR:
-		if r.Siz != 4 {
-			return false
-		}
-		ctxt.Out.Write32(uint32(elf.R_MIPS_32) | uint32(elfsym)<<8)
-	case objabi.R_ADDRMIPS:
-		ctxt.Out.Write32(uint32(elf.R_MIPS_LO16) | uint32(elfsym)<<8)
-	case objabi.R_ADDRMIPSU:
-		ctxt.Out.Write32(uint32(elf.R_MIPS_HI16) | uint32(elfsym)<<8)
-	case objabi.R_ADDRMIPSTLS:
-		ctxt.Out.Write32(uint32(elf.R_MIPS_TLS_TPREL_LO16) | uint32(elfsym)<<8)
-	case objabi.R_CALLMIPS, objabi.R_JMPMIPS:
-		ctxt.Out.Write32(uint32(elf.R_MIPS_26) | uint32(elfsym)<<8)
-	}
-
-	return true
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-	return
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-	return false
-}
-
-func applyrel(arch *sys.Arch, r *sym.Reloc, s *sym.Symbol, val int64, t int64) int64 {
-	o := arch.ByteOrder.Uint32(s.P[r.Off:])
-	switch r.Type {
-	case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSTLS:
-		return int64(o&0xffff0000 | uint32(t)&0xffff)
-	case objabi.R_ADDRMIPSU:
-		return int64(o&0xffff0000 | uint32((t+(1<<15))>>16)&0xffff)
-	case objabi.R_CALLMIPS, objabi.R_JMPMIPS:
-		return int64(o&0xfc000000 | uint32(t>>2)&^0xfc000000)
-	default:
-		return val
-	}
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-	if ctxt.LinkMode == ld.LinkExternal {
-		switch r.Type {
-		default:
-			return val, false
-		case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSU:
-			r.Done = false
-
-			// set up addend for eventual relocation via outer symbol.
-			rs := r.Sym
-			r.Xadd = r.Add
-			for rs.Outer != nil {
-				r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
-				rs = rs.Outer
-			}
-
-			if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
-				ld.Errorf(s, "missing section for %s", rs.Name)
-			}
-			r.Xsym = rs
-			return applyrel(ctxt.Arch, r, s, val, r.Xadd), true
-		case objabi.R_ADDRMIPSTLS, objabi.R_CALLMIPS, objabi.R_JMPMIPS:
-			r.Done = false
-			r.Xsym = r.Sym
-			r.Xadd = r.Add
-			return applyrel(ctxt.Arch, r, s, val, r.Add), true
-		}
-	}
-
-	switch r.Type {
-	case objabi.R_CONST:
-		return r.Add, true
-	case objabi.R_GOTOFF:
-		return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
-	case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSU:
-		t := ld.Symaddr(r.Sym) + r.Add
-		return applyrel(ctxt.Arch, r, s, val, t), true
-	case objabi.R_CALLMIPS, objabi.R_JMPMIPS:
-		t := ld.Symaddr(r.Sym) + r.Add
-
-		if t&3 != 0 {
-			ld.Errorf(s, "direct call is not aligned: %s %x", r.Sym.Name, t)
-		}
-
-		// check if target address is in the same 256 MB region as the next instruction
-		if (s.Value+int64(r.Off)+4)&0xf0000000 != (t & 0xf0000000) {
-			ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
-		}
-
-		return applyrel(ctxt.Arch, r, s, val, t), true
-	case objabi.R_ADDRMIPSTLS:
-		// thread pointer is at 0x7000 offset from the start of TLS data area
-		t := ld.Symaddr(r.Sym) + r.Add - 0x7000
-		if t < -32768 || t >= 32678 {
-			ld.Errorf(s, "TLS offset out of range %d", t)
-		}
-		return applyrel(ctxt.Arch, r, s, val, t), true
-	}
-
-	return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-	return -1
-}
-
-func asmb(ctxt *ld.Link) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	sect := ld.Segtext.Sections[0]
-	ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-	ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-	for _, sect = range ld.Segtext.Sections[1:] {
-		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-		ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-	}
-
-	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-	/* output symbol table */
-	ld.Symsize = 0
-
-	ld.Lcsize = 0
-	symo := uint32(0)
-	if !*ld.FlagS {
-		if !ctxt.IsELF {
-			ld.Errorf(nil, "unsupported executable format")
-		}
-		symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-		symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
-
-		ctxt.Out.SeekSet(int64(symo))
-		ld.Asmelfsym(ctxt)
-		ctxt.Out.Flush()
-		ctxt.Out.Write(ld.Elfstrdat)
-
-		if ctxt.LinkMode == ld.LinkExternal {
-			ld.Elfemitreloc(ctxt)
-		}
-	}
-
-	ctxt.Out.SeekSet(0)
-	switch ctxt.HeadType {
-	default:
-		ld.Errorf(nil, "unsupported operating system")
-	case objabi.Hlinux:
-		ld.Asmbelf(ctxt, int64(symo))
-	}
-
-	ctxt.Out.Flush()
-	if *ld.FlagC {
-		fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
-		fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
-		fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
-		fmt.Printf("symsize=%d\n", ld.Symsize)
-		fmt.Printf("lcsize=%d\n", ld.Lcsize)
-		fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
-	}
-}
diff --git a/src/cmd/oldlink/internal/mips/l.go b/src/cmd/oldlink/internal/mips/l.go
deleted file mode 100644
index adbde40..0000000
--- a/src/cmd/oldlink/internal/mips/l.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2016 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package mips
-
-// Writing object files.
-
-// cmd/9l/l.h from Vita Nuova.
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
-//	Portions Copyright © 2016 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-const (
-	MaxAlign  = 32 // max data alignment
-	MinAlign  = 1  // min data alignment
-	FuncAlign = 4
-)
-
-/* Used by ../internal/ld/dwarf.go */
-const (
-	DWARFREGSP = 29
-	DWARFREGLR = 31
-)
diff --git a/src/cmd/oldlink/internal/mips/obj.go b/src/cmd/oldlink/internal/mips/obj.go
deleted file mode 100644
index c80824f..0000000
--- a/src/cmd/oldlink/internal/mips/obj.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// Inferno utils/5l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/obj.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2016 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package mips
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-	arch := sys.ArchMIPS
-	if objabi.GOARCH == "mipsle" {
-		arch = sys.ArchMIPSLE
-	}
-
-	theArch := ld.Arch{
-		Funcalign:  FuncAlign,
-		Maxalign:   MaxAlign,
-		Minalign:   MinAlign,
-		Dwarfregsp: DWARFREGSP,
-		Dwarfreglr: DWARFREGLR,
-
-		Adddynrel:        adddynrel,
-		Archinit:         archinit,
-		Archreloc:        archreloc,
-		Archrelocvariant: archrelocvariant,
-		Asmb:             asmb,
-		Asmb2:            asmb2,
-		Elfreloc1:        elfreloc1,
-		Elfsetupplt:      elfsetupplt,
-		Gentext:          gentext,
-		Machoreloc1:      machoreloc1,
-
-		Linuxdynld: "/lib/ld.so.1",
-
-		Freebsddynld:   "XXX",
-		Openbsddynld:   "XXX",
-		Netbsddynld:    "XXX",
-		Dragonflydynld: "XXX",
-		Solarisdynld:   "XXX",
-	}
-
-	return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-	switch ctxt.HeadType {
-	default:
-		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-	case objabi.Hlinux: /* mips elf */
-		ld.Elfinit(ctxt)
-		ld.HEADR = ld.ELFRESERVE
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 0x10000
-		}
-	}
-}
diff --git a/src/cmd/oldlink/internal/mips64/asm.go b/src/cmd/oldlink/internal/mips64/asm.go
deleted file mode 100644
index 775b74e..0000000
--- a/src/cmd/oldlink/internal/mips64/asm.go
+++ /dev/null
@@ -1,278 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package mips64
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-	"cmd/oldlink/internal/sym"
-	"debug/elf"
-	"fmt"
-	"log"
-)
-
-func gentext(ctxt *ld.Link) {}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-	log.Fatalf("adddynrel not implemented")
-	return false
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-	// mips64 ELF relocation (endian neutral)
-	//		offset	uint64
-	//		sym		uint32
-	//		ssym	uint8
-	//		type3	uint8
-	//		type2	uint8
-	//		type	uint8
-	//		addend	int64
-
-	ctxt.Out.Write64(uint64(sectoff))
-
-	elfsym := r.Xsym.ElfsymForReloc()
-	ctxt.Out.Write32(uint32(elfsym))
-	ctxt.Out.Write8(0)
-	ctxt.Out.Write8(0)
-	ctxt.Out.Write8(0)
-	switch r.Type {
-	default:
-		return false
-	case objabi.R_ADDR:
-		switch r.Siz {
-		case 4:
-			ctxt.Out.Write8(uint8(elf.R_MIPS_32))
-		case 8:
-			ctxt.Out.Write8(uint8(elf.R_MIPS_64))
-		default:
-			return false
-		}
-	case objabi.R_ADDRMIPS:
-		ctxt.Out.Write8(uint8(elf.R_MIPS_LO16))
-	case objabi.R_ADDRMIPSU:
-		ctxt.Out.Write8(uint8(elf.R_MIPS_HI16))
-	case objabi.R_ADDRMIPSTLS:
-		ctxt.Out.Write8(uint8(elf.R_MIPS_TLS_TPREL_LO16))
-	case objabi.R_CALLMIPS,
-		objabi.R_JMPMIPS:
-		ctxt.Out.Write8(uint8(elf.R_MIPS_26))
-	}
-	ctxt.Out.Write64(uint64(r.Xadd))
-
-	return true
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-	return
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-	return false
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-	if ctxt.LinkMode == ld.LinkExternal {
-		switch r.Type {
-		default:
-			return val, false
-		case objabi.R_ADDRMIPS,
-			objabi.R_ADDRMIPSU:
-			r.Done = false
-
-			// set up addend for eventual relocation via outer symbol.
-			rs := r.Sym
-			r.Xadd = r.Add
-			for rs.Outer != nil {
-				r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
-				rs = rs.Outer
-			}
-
-			if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
-				ld.Errorf(s, "missing section for %s", rs.Name)
-			}
-			r.Xsym = rs
-
-			return val, true
-		case objabi.R_ADDRMIPSTLS,
-			objabi.R_CALLMIPS,
-			objabi.R_JMPMIPS:
-			r.Done = false
-			r.Xsym = r.Sym
-			r.Xadd = r.Add
-			return val, true
-		}
-	}
-
-	switch r.Type {
-	case objabi.R_CONST:
-		return r.Add, true
-	case objabi.R_GOTOFF:
-		return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
-	case objabi.R_ADDRMIPS,
-		objabi.R_ADDRMIPSU:
-		t := ld.Symaddr(r.Sym) + r.Add
-		o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
-		if r.Type == objabi.R_ADDRMIPS {
-			return int64(o1&0xffff0000 | uint32(t)&0xffff), true
-		}
-		return int64(o1&0xffff0000 | uint32((t+1<<15)>>16)&0xffff), true
-	case objabi.R_ADDRMIPSTLS:
-		// thread pointer is at 0x7000 offset from the start of TLS data area
-		t := ld.Symaddr(r.Sym) + r.Add - 0x7000
-		if t < -32768 || t >= 32678 {
-			ld.Errorf(s, "TLS offset out of range %d", t)
-		}
-		o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
-		return int64(o1&0xffff0000 | uint32(t)&0xffff), true
-	case objabi.R_CALLMIPS,
-		objabi.R_JMPMIPS:
-		// Low 26 bits = (S + A) >> 2
-		t := ld.Symaddr(r.Sym) + r.Add
-		o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
-		return int64(o1&0xfc000000 | uint32(t>>2)&^0xfc000000), true
-	}
-
-	return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-	return -1
-}
-
-func asmb(ctxt *ld.Link) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	sect := ld.Segtext.Sections[0]
-	ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-	ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-	for _, sect = range ld.Segtext.Sections[1:] {
-		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-		ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-	}
-	if ld.Segrelrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
-	}
-
-	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-	/* output symbol table */
-	ld.Symsize = 0
-
-	ld.Lcsize = 0
-	symo := uint32(0)
-	if !*ld.FlagS {
-		// TODO: rationalize
-		switch ctxt.HeadType {
-		default:
-			if ctxt.IsELF {
-				symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-				symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
-			}
-
-		case objabi.Hplan9:
-			symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
-		}
-
-		ctxt.Out.SeekSet(int64(symo))
-		switch ctxt.HeadType {
-		default:
-			if ctxt.IsELF {
-				ld.Asmelfsym(ctxt)
-				ctxt.Out.Flush()
-				ctxt.Out.Write(ld.Elfstrdat)
-
-				if ctxt.LinkMode == ld.LinkExternal {
-					ld.Elfemitreloc(ctxt)
-				}
-			}
-
-		case objabi.Hplan9:
-			ld.Asmplan9sym(ctxt)
-			ctxt.Out.Flush()
-
-			sym := ctxt.Syms.Lookup("pclntab", 0)
-			if sym != nil {
-				ld.Lcsize = int32(len(sym.P))
-				ctxt.Out.Write(sym.P)
-				ctxt.Out.Flush()
-			}
-		}
-	}
-
-	ctxt.Out.SeekSet(0)
-	switch ctxt.HeadType {
-	default:
-	case objabi.Hplan9: /* plan 9 */
-		magic := uint32(4*18*18 + 7)
-		if ctxt.Arch == sys.ArchMIPS64LE {
-			magic = uint32(4*26*26 + 7)
-		}
-		ctxt.Out.Write32(magic)                      /* magic */
-		ctxt.Out.Write32(uint32(ld.Segtext.Filelen)) /* sizes */
-		ctxt.Out.Write32(uint32(ld.Segdata.Filelen))
-		ctxt.Out.Write32(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-		ctxt.Out.Write32(uint32(ld.Symsize))          /* nsyms */
-		ctxt.Out.Write32(uint32(ld.Entryvalue(ctxt))) /* va of entry */
-		ctxt.Out.Write32(0)
-		ctxt.Out.Write32(uint32(ld.Lcsize))
-
-	case objabi.Hlinux,
-		objabi.Hfreebsd,
-		objabi.Hnetbsd,
-		objabi.Hopenbsd:
-		ld.Asmbelf(ctxt, int64(symo))
-	}
-
-	ctxt.Out.Flush()
-	if *ld.FlagC {
-		fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
-		fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
-		fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
-		fmt.Printf("symsize=%d\n", ld.Symsize)
-		fmt.Printf("lcsize=%d\n", ld.Lcsize)
-		fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
-	}
-}
diff --git a/src/cmd/oldlink/internal/mips64/l.go b/src/cmd/oldlink/internal/mips64/l.go
deleted file mode 100644
index d794122..0000000
--- a/src/cmd/oldlink/internal/mips64/l.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package mips64
-
-// Writing object files.
-
-// cmd/9l/l.h from Vita Nuova.
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-const (
-	maxAlign  = 32 // max data alignment
-	minAlign  = 1  // min data alignment
-	funcAlign = 8
-)
-
-/* Used by ../internal/ld/dwarf.go */
-const (
-	dwarfRegSP = 29
-	dwarfRegLR = 31
-)
diff --git a/src/cmd/oldlink/internal/mips64/obj.go b/src/cmd/oldlink/internal/mips64/obj.go
deleted file mode 100644
index 1ddce45..0000000
--- a/src/cmd/oldlink/internal/mips64/obj.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// Inferno utils/5l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/obj.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package mips64
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-	arch := sys.ArchMIPS64
-	if objabi.GOARCH == "mips64le" {
-		arch = sys.ArchMIPS64LE
-	}
-
-	theArch := ld.Arch{
-		Funcalign:        funcAlign,
-		Maxalign:         maxAlign,
-		Minalign:         minAlign,
-		Dwarfregsp:       dwarfRegSP,
-		Dwarfreglr:       dwarfRegLR,
-		Adddynrel:        adddynrel,
-		Archinit:         archinit,
-		Archreloc:        archreloc,
-		Archrelocvariant: archrelocvariant,
-		Asmb:             asmb,
-		Asmb2:            asmb2,
-		Elfreloc1:        elfreloc1,
-		Elfsetupplt:      elfsetupplt,
-		Gentext:          gentext,
-		Machoreloc1:      machoreloc1,
-
-		Linuxdynld:     "/lib64/ld64.so.1",
-		Freebsddynld:   "XXX",
-		Openbsddynld:   "XXX",
-		Netbsddynld:    "XXX",
-		Dragonflydynld: "XXX",
-		Solarisdynld:   "XXX",
-	}
-
-	return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-	switch ctxt.HeadType {
-	default:
-		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-
-	case objabi.Hplan9: /* plan 9 */
-		ld.HEADR = 32
-
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 16*1024 + int64(ld.HEADR)
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 16 * 1024
-		}
-
-	case objabi.Hlinux: /* mips64 elf */
-		ld.Elfinit(ctxt)
-		ld.HEADR = ld.ELFRESERVE
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 0x10000
-		}
-	}
-}
diff --git a/src/cmd/oldlink/internal/objfile/objfile.go b/src/cmd/oldlink/internal/objfile/objfile.go
deleted file mode 100644
index 6882b76..0000000
--- a/src/cmd/oldlink/internal/objfile/objfile.go
+++ /dev/null
@@ -1,664 +0,0 @@
-// 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.
-
-// Package objfile reads Go object files for the Go linker, cmd/link.
-//
-// This package is similar to cmd/internal/objfile which also reads
-// Go object files.
-package objfile
-
-import (
-	"bufio"
-	"bytes"
-	"cmd/internal/bio"
-	"cmd/internal/dwarf"
-	"cmd/internal/goobj2"
-	"cmd/internal/obj"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/sym"
-	"fmt"
-	"internal/unsafeheader"
-	"io"
-	"log"
-	"os"
-	"strconv"
-	"strings"
-	"unsafe"
-)
-
-const (
-	startmagic = "\x00go114ld"
-	endmagic   = "\xffgo114ld"
-)
-
-var emptyPkg = []byte(`"".`)
-
-// objReader reads Go object files.
-type objReader struct {
-	rd              *bio.Reader
-	arch            *sys.Arch
-	syms            *sym.Symbols
-	lib             *sym.Library
-	unit            *sym.CompilationUnit
-	pn              string
-	dupSym          *sym.Symbol
-	localSymVersion int
-	flags           int
-	strictDupMsgs   int
-	dataSize        int
-
-	// rdBuf is used by readString and readSymName as scratch for reading strings.
-	rdBuf []byte
-
-	// List of symbol references for the file being read.
-	refs        []*sym.Symbol
-	data        []byte
-	reloc       []sym.Reloc
-	pcdata      []sym.Pcdata
-	funcdata    []*sym.Symbol
-	funcdataoff []int64
-	file        []*sym.Symbol
-	pkgpref     string // objabi.PathToPrefix(r.lib.Pkg) + "."
-
-	roObject []byte // from read-only mmap of object file (may be nil)
-	roOffset int64  // offset into readonly object data examined so far
-
-	dataReadOnly bool // whether data is backed by read-only memory
-}
-
-// Flags to enable optional behavior during object loading/reading.
-
-const (
-	NoFlag int = iota
-
-	// Sanity-check duplicate symbol contents, issuing warning
-	// when duplicates have different lengths or contents.
-	StrictDupsWarnFlag
-
-	// Similar to StrictDupsWarnFlag, but issue fatal error.
-	StrictDupsErrFlag
-)
-
-// Load loads an object file f into library lib.
-// The symbols loaded are added to syms.
-func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, lib *sym.Library, unit *sym.CompilationUnit, length int64, pn string, flags int) int {
-	start := f.Offset()
-	roObject := f.SliceRO(uint64(length))
-	if roObject != nil {
-		f.MustSeek(int64(-length), os.SEEK_CUR)
-	}
-	r := &objReader{
-		rd:              f,
-		lib:             lib,
-		unit:            unit,
-		arch:            arch,
-		syms:            syms,
-		pn:              pn,
-		dupSym:          &sym.Symbol{Name: ".dup"},
-		localSymVersion: syms.IncVersion(),
-		flags:           flags,
-		roObject:        roObject,
-		pkgpref:         objabi.PathToPrefix(lib.Pkg) + ".",
-	}
-	r.loadObjFile()
-	if roObject != nil {
-		if r.roOffset != length {
-			log.Fatalf("%s: unexpected end at %d, want %d", pn, r.roOffset, start+length)
-		}
-		r.rd.MustSeek(int64(length), os.SEEK_CUR)
-	} else if f.Offset() != start+length {
-		log.Fatalf("%s: unexpected end at %d, want %d", pn, f.Offset(), start+length)
-	}
-	return r.strictDupMsgs
-}
-
-func (r *objReader) loadObjFile() {
-	// Magic header
-	var buf [8]uint8
-	r.readFull(buf[:])
-	if string(buf[:]) != startmagic {
-		if string(buf[:]) == goobj2.Magic {
-			log.Fatalf("found object file %s in new format, but -go115newobj is false\nset -go115newobj consistently in all -gcflags, -asmflags, and -ldflags", r.pn)
-		}
-		log.Fatalf("%s: invalid file start %x %x %x %x %x %x %x %x", r.pn, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7])
-	}
-
-	// Version
-	c, err := r.readByte()
-	if err != nil || c != 1 {
-		log.Fatalf("%s: invalid file version number %d", r.pn, c)
-	}
-
-	// Autolib
-	for {
-		lib := r.readString()
-		if lib == "" {
-			break
-		}
-		r.lib.ImportStrings = append(r.lib.ImportStrings, lib)
-	}
-
-	// DWARF strings
-	count := r.readInt()
-	r.unit.DWARFFileTable = make([]string, count)
-	for i := 0; i < count; i++ {
-		// TODO: This should probably be a call to mkROString.
-		r.unit.DWARFFileTable[i] = r.readString()
-	}
-
-	// Symbol references
-	r.refs = []*sym.Symbol{nil} // zeroth ref is nil
-	for {
-		c, err := r.peek(1)
-		if err != nil {
-			log.Fatalf("%s: peeking: %v", r.pn, err)
-		}
-		if c[0] == 0xff {
-			r.readByte()
-			break
-		}
-		r.readRef()
-	}
-
-	// Lengths
-	r.readSlices()
-
-	// Data section
-	err = r.readDataSection()
-	if err != nil {
-		log.Fatalf("%s: error reading %s", r.pn, err)
-	}
-
-	// Defined symbols
-	for {
-		c, err := r.peek(1)
-		if err != nil {
-			log.Fatalf("%s: peeking: %v", r.pn, err)
-		}
-		if c[0] == 0xff {
-			break
-		}
-		r.readSym()
-	}
-
-	// Magic footer
-	buf = [8]uint8{}
-	r.readFull(buf[:])
-	if string(buf[:]) != endmagic {
-		log.Fatalf("%s: invalid file end", r.pn)
-	}
-}
-
-func (r *objReader) readSlices() {
-	r.dataSize = r.readInt()
-	n := r.readInt()
-	r.reloc = make([]sym.Reloc, n)
-	n = r.readInt()
-	r.pcdata = make([]sym.Pcdata, n)
-	_ = r.readInt() // TODO: remove on next object file rev (autom count)
-	n = r.readInt()
-	r.funcdata = make([]*sym.Symbol, n)
-	r.funcdataoff = make([]int64, n)
-	n = r.readInt()
-	r.file = make([]*sym.Symbol, n)
-}
-
-func (r *objReader) readDataSection() (err error) {
-	if r.roObject != nil {
-		r.data, r.dataReadOnly, err =
-			r.roObject[r.roOffset:r.roOffset+int64(r.dataSize)], true, nil
-		r.roOffset += int64(r.dataSize)
-		return
-	}
-	r.data, r.dataReadOnly, err = r.rd.Slice(uint64(r.dataSize))
-	return
-}
-
-// Symbols are prefixed so their content doesn't get confused with the magic footer.
-const symPrefix = 0xfe
-
-func (r *objReader) readSym() {
-	var c byte
-	var err error
-	if c, err = r.readByte(); c != symPrefix || err != nil {
-		log.Fatalln("readSym out of sync")
-	}
-	if c, err = r.readByte(); err != nil {
-		log.Fatalln("error reading input: ", err)
-	}
-	t := sym.AbiSymKindToSymKind[c]
-	s := r.readSymIndex()
-	flags := r.readInt()
-	dupok := flags&1 != 0
-	local := flags&2 != 0
-	makeTypelink := flags&4 != 0
-	size := r.readInt()
-	typ := r.readSymIndex()
-	data := r.readData()
-	nreloc := r.readInt()
-	isdup := false
-
-	var dup *sym.Symbol
-	if s.Type != 0 && s.Type != sym.SXREF {
-		if (t == sym.SDATA || t == sym.SBSS || t == sym.SNOPTRBSS) && len(data) == 0 && nreloc == 0 {
-			if s.Size < int64(size) {
-				s.Size = int64(size)
-			}
-			if typ != nil && s.Gotype == nil {
-				s.Gotype = typ
-			}
-			return
-		}
-
-		if (s.Type == sym.SDATA || s.Type == sym.SBSS || s.Type == sym.SNOPTRBSS) && len(s.P) == 0 && len(s.R) == 0 {
-			goto overwrite
-		}
-		if s.Type != sym.SBSS && s.Type != sym.SNOPTRBSS && !dupok && !s.Attr.DuplicateOK() {
-			log.Fatalf("duplicate symbol %s (types %d and %d) in %s and %s", s.Name, s.Type, t, s.File, r.pn)
-		}
-		if len(s.P) > 0 {
-			dup = s
-			s = r.dupSym
-			isdup = true
-		}
-	}
-
-overwrite:
-	s.File = r.pkgpref[:len(r.pkgpref)-1]
-	s.Unit = r.unit
-	if dupok {
-		s.Attr |= sym.AttrDuplicateOK
-	}
-	if t == sym.SXREF {
-		log.Fatalf("bad sxref")
-	}
-	if t == 0 {
-		log.Fatalf("missing type for %s in %s", s.Name, r.pn)
-	}
-	if t == sym.SBSS && (s.Type == sym.SRODATA || s.Type == sym.SNOPTRBSS) {
-		t = s.Type
-	}
-	s.Type = t
-	if s.Size < int64(size) {
-		s.Size = int64(size)
-	}
-	s.Attr.Set(sym.AttrLocal, local)
-	s.Attr.Set(sym.AttrMakeTypelink, makeTypelink)
-	if typ != nil {
-		s.Gotype = typ
-	}
-	if isdup && typ != nil { // if bss sym defined multiple times, take type from any one def
-		dup.Gotype = typ
-	}
-	s.P = data
-	s.Attr.Set(sym.AttrReadOnly, r.dataReadOnly)
-	if nreloc > 0 {
-		s.R = r.reloc[:nreloc:nreloc]
-		if !isdup {
-			r.reloc = r.reloc[nreloc:]
-		}
-
-		for i := 0; i < nreloc; i++ {
-			s.R[i] = sym.Reloc{
-				Off:  r.readInt32(),
-				Siz:  r.readUint8(),
-				Type: objabi.RelocType(r.readInt32()),
-				Add:  r.readInt64(),
-				Sym:  r.readSymIndex(),
-			}
-		}
-	}
-
-	if s.Type == sym.STEXT {
-		s.FuncInfo = new(sym.FuncInfo)
-		pc := s.FuncInfo
-
-		pc.Args = r.readInt32()
-		pc.Locals = r.readInt32()
-		s.Align = r.readInt32()
-		if r.readUint8() != 0 {
-			s.Attr |= sym.AttrNoSplit
-		}
-		flags := r.readInt()
-		if flags&(1<<2) != 0 {
-			s.Attr |= sym.AttrReflectMethod
-		}
-		if flags&(1<<3) != 0 {
-			s.Attr |= sym.AttrShared
-		}
-		if flags&(1<<4) != 0 {
-			s.Attr |= sym.AttrTopFrame
-		}
-		n := r.readInt()
-		if n != 0 {
-			log.Fatalf("stale object file: autom count nonzero")
-		}
-
-		pc.Pcsp.P = r.readData()
-		pc.Pcfile.P = r.readData()
-		pc.Pcline.P = r.readData()
-		pc.Pcinline.P = r.readData()
-		n = r.readInt()
-		pc.Pcdata = r.pcdata[:n:n]
-		if !isdup {
-			r.pcdata = r.pcdata[n:]
-		}
-		for i := 0; i < n; i++ {
-			pc.Pcdata[i].P = r.readData()
-		}
-		n = r.readInt()
-		pc.Funcdata = r.funcdata[:n:n]
-		pc.Funcdataoff = r.funcdataoff[:n:n]
-		if !isdup {
-			r.funcdata = r.funcdata[n:]
-			r.funcdataoff = r.funcdataoff[n:]
-		}
-		for i := 0; i < n; i++ {
-			pc.Funcdata[i] = r.readSymIndex()
-		}
-		for i := 0; i < n; i++ {
-			pc.Funcdataoff[i] = r.readInt64()
-		}
-		n = r.readInt()
-		pc.File = r.file[:n:n]
-		if !isdup {
-			r.file = r.file[n:]
-		}
-		for i := 0; i < n; i++ {
-			pc.File[i] = r.readSymIndex()
-		}
-		n = r.readInt()
-		pc.InlTree = make([]sym.InlinedCall, n)
-		for i := 0; i < n; i++ {
-			pc.InlTree[i].Parent = r.readInt32()
-			pc.InlTree[i].File = r.readSymIndex()
-			pc.InlTree[i].Line = r.readInt32()
-			pc.InlTree[i].Func = r.readSymIndex().Name
-			pc.InlTree[i].ParentPC = r.readInt32()
-		}
-
-		if !dupok {
-			if s.Attr.OnList() {
-				log.Fatalf("symbol %s listed multiple times", s.Name)
-			}
-			s.Attr |= sym.AttrOnList
-			r.lib.Textp = append(r.lib.Textp, s)
-		} else {
-			// there may ba a dup in another package
-			// put into a temp list and add to text later
-			if !isdup {
-				r.lib.DupTextSyms = append(r.lib.DupTextSyms, s)
-			} else {
-				r.lib.DupTextSyms = append(r.lib.DupTextSyms, dup)
-			}
-		}
-	}
-	if s.Type == sym.SDWARFINFO {
-		r.patchDWARFName(s)
-	}
-
-	if isdup && r.flags&(StrictDupsWarnFlag|StrictDupsErrFlag) != 0 {
-		// Compare the just-read symbol with the previously read
-		// symbol of the same name, verifying that they have the same
-		// payload. If not, issue a warning and possibly an error.
-		if !bytes.Equal(s.P, dup.P) {
-			reason := "same length but different contents"
-			if len(s.P) != len(dup.P) {
-				reason = fmt.Sprintf("new length %d != old length %d",
-					len(data), len(dup.P))
-			}
-			fmt.Fprintf(os.Stderr, "cmd/link: while reading object for '%v': duplicate symbol '%s', previous def at '%v', with mismatched payload: %s\n", r.lib, dup, dup.Unit.Lib, reason)
-
-			// For the moment, whitelist DWARF subprogram DIEs for
-			// auto-generated wrapper functions. What seems to happen
-			// here is that we get different line numbers on formal
-			// params; I am guessing that the pos is being inherited
-			// from the spot where the wrapper is needed.
-			whitelist := (strings.HasPrefix(dup.Name, "go.info.go.interface") ||
-				strings.HasPrefix(dup.Name, "go.info.go.builtin") ||
-				strings.HasPrefix(dup.Name, "go.isstmt.go.builtin") ||
-				strings.HasPrefix(dup.Name, "go.debuglines"))
-			if !whitelist {
-				r.strictDupMsgs++
-			}
-		}
-	}
-}
-
-func (r *objReader) patchDWARFName(s *sym.Symbol) {
-	// This is kind of ugly. Really the package name should not
-	// even be included here.
-	if s.Size < 1 || s.P[0] != dwarf.DW_ABRV_FUNCTION {
-		return
-	}
-	e := bytes.IndexByte(s.P, 0)
-	if e == -1 {
-		return
-	}
-	p := bytes.Index(s.P[:e], emptyPkg)
-	if p == -1 {
-		return
-	}
-	pkgprefix := []byte(r.pkgpref)
-	patched := bytes.Replace(s.P[:e], emptyPkg, pkgprefix, -1)
-
-	s.P = append(patched, s.P[e:]...)
-	delta := int64(len(s.P)) - s.Size
-	s.Size = int64(len(s.P))
-	for i := range s.R {
-		r := &s.R[i]
-		if r.Off > int32(e) {
-			r.Off += int32(delta)
-		}
-	}
-}
-
-func (r *objReader) readFull(b []byte) {
-	if r.roObject != nil {
-		copy(b, r.roObject[r.roOffset:])
-		r.roOffset += int64(len(b))
-		return
-	}
-	_, err := io.ReadFull(r.rd, b)
-	if err != nil {
-		log.Fatalf("%s: error reading %s", r.pn, err)
-	}
-}
-
-func (r *objReader) readByte() (byte, error) {
-	if r.roObject != nil {
-		b := r.roObject[r.roOffset]
-		r.roOffset++
-		return b, nil
-	}
-	return r.rd.ReadByte()
-}
-
-func (r *objReader) peek(n int) ([]byte, error) {
-	if r.roObject != nil {
-		return r.roObject[r.roOffset : r.roOffset+int64(n)], nil
-	}
-	return r.rd.Peek(n)
-}
-
-func (r *objReader) readRef() {
-	if c, err := r.readByte(); c != symPrefix || err != nil {
-		log.Fatalf("readSym out of sync")
-	}
-	name := r.readSymName()
-	var v int
-	if abi := r.readInt(); abi == -1 {
-		// Static
-		v = r.localSymVersion
-	} else if abiver := sym.ABIToVersion(obj.ABI(abi)); abiver != -1 {
-		// Note that data symbols are "ABI0", which maps to version 0.
-		v = abiver
-	} else {
-		log.Fatalf("invalid symbol ABI for %q: %d", name, abi)
-	}
-	s := r.syms.Lookup(name, v)
-	r.refs = append(r.refs, s)
-
-	if s == nil || v == r.localSymVersion {
-		return
-	}
-	if s.Name[0] == '$' && len(s.Name) > 5 && s.Type == 0 && len(s.P) == 0 {
-		x, err := strconv.ParseUint(s.Name[5:], 16, 64)
-		if err != nil {
-			log.Panicf("failed to parse $-symbol %s: %v", s.Name, err)
-		}
-		s.Type = sym.SRODATA
-		s.Attr |= sym.AttrLocal
-		switch s.Name[:5] {
-		case "$f32.":
-			if uint64(uint32(x)) != x {
-				log.Panicf("$-symbol %s too large: %d", s.Name, x)
-			}
-			s.AddUint32(r.arch, uint32(x))
-		case "$f64.", "$i64.":
-			s.AddUint64(r.arch, x)
-		default:
-			log.Panicf("unrecognized $-symbol: %s", s.Name)
-		}
-		s.Attr.Set(sym.AttrReachable, false)
-	}
-	if strings.HasPrefix(s.Name, "runtime.gcbits.") {
-		s.Attr |= sym.AttrLocal
-	}
-}
-
-func (r *objReader) readInt64() int64 {
-	uv := uint64(0)
-	for shift := uint(0); ; shift += 7 {
-		if shift >= 64 {
-			log.Fatalf("corrupt input")
-		}
-		c, err := r.readByte()
-		if err != nil {
-			log.Fatalln("error reading input: ", err)
-		}
-		uv |= uint64(c&0x7F) << shift
-		if c&0x80 == 0 {
-			break
-		}
-	}
-
-	return int64(uv>>1) ^ (int64(uv<<63) >> 63)
-}
-
-func (r *objReader) readInt() int {
-	n := r.readInt64()
-	if int64(int(n)) != n {
-		log.Panicf("%v out of range for int", n)
-	}
-	return int(n)
-}
-
-func (r *objReader) readInt32() int32 {
-	n := r.readInt64()
-	if int64(int32(n)) != n {
-		log.Panicf("%v out of range for int32", n)
-	}
-	return int32(n)
-}
-
-func (r *objReader) readInt16() int16 {
-	n := r.readInt64()
-	if int64(int16(n)) != n {
-		log.Panicf("%v out of range for int16", n)
-	}
-	return int16(n)
-}
-
-func (r *objReader) readUint8() uint8 {
-	n := r.readInt64()
-	if int64(uint8(n)) != n {
-		log.Panicf("%v out of range for uint8", n)
-	}
-	return uint8(n)
-}
-
-func (r *objReader) readString() string {
-	n := r.readInt()
-	if cap(r.rdBuf) < n {
-		r.rdBuf = make([]byte, 2*n)
-	}
-	r.readFull(r.rdBuf[:n])
-	return string(r.rdBuf[:n])
-}
-
-func (r *objReader) readData() []byte {
-	n := r.readInt()
-	p := r.data[:n:n]
-	r.data = r.data[n:]
-	return p
-}
-
-func mkROString(rodata []byte) string {
-	if len(rodata) == 0 {
-		return ""
-	}
-
-	var s string
-	hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
-	hdr.Data = unsafe.Pointer(&rodata[0])
-	hdr.Len = len(rodata)
-
-	return s
-}
-
-// readSymName reads a symbol name, replacing all "". with pkg.
-func (r *objReader) readSymName() string {
-	n := r.readInt()
-	if n == 0 {
-		r.readInt64()
-		return ""
-	}
-	if cap(r.rdBuf) < n {
-		r.rdBuf = make([]byte, 2*n)
-	}
-	sOffset := r.roOffset
-	origName, err := r.peek(n)
-	if err == bufio.ErrBufferFull {
-		// Long symbol names are rare but exist. One source is type
-		// symbols for types with long string forms. See #15104.
-		origName = make([]byte, n)
-		r.readFull(origName)
-	} else if err != nil {
-		log.Fatalf("%s: error reading symbol: %v", r.pn, err)
-	}
-	adjName := r.rdBuf[:0]
-	nPkgRefs := 0
-	for {
-		i := bytes.Index(origName, emptyPkg)
-		if i == -1 {
-			var s string
-			if r.roObject != nil && nPkgRefs == 0 {
-				s = mkROString(r.roObject[sOffset : sOffset+int64(n)])
-			} else {
-				s = string(append(adjName, origName...))
-			}
-			// Read past the peeked origName, now that we're done with it,
-			// using the rfBuf (also no longer used) as the scratch space.
-			// TODO: use bufio.Reader.Discard if available instead?
-			if err == nil {
-				r.readFull(r.rdBuf[:n])
-			}
-			r.rdBuf = adjName[:0] // in case 2*n wasn't enough
-			return s
-		}
-		nPkgRefs++
-		adjName = append(adjName, origName[:i]...)
-		adjName = append(adjName, r.pkgpref[:len(r.pkgpref)-1]...)
-		adjName = append(adjName, '.')
-		origName = origName[i+len(emptyPkg):]
-	}
-}
-
-// Reads the index of a symbol reference and resolves it to a symbol
-func (r *objReader) readSymIndex() *sym.Symbol {
-	i := r.readInt()
-	return r.refs[i]
-}
diff --git a/src/cmd/oldlink/internal/ppc64/asm.go b/src/cmd/oldlink/internal/ppc64/asm.go
deleted file mode 100644
index 608bdec..0000000
--- a/src/cmd/oldlink/internal/ppc64/asm.go
+++ /dev/null
@@ -1,1181 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ppc64
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-	"cmd/oldlink/internal/sym"
-	"debug/elf"
-	"encoding/binary"
-	"fmt"
-	"log"
-	"strings"
-)
-
-func genplt(ctxt *ld.Link) {
-	// The ppc64 ABI PLT has similar concepts to other
-	// architectures, but is laid out quite differently. When we
-	// see an R_PPC64_REL24 relocation to a dynamic symbol
-	// (indicating that the call needs to go through the PLT), we
-	// generate up to three stubs and reserve a PLT slot.
-	//
-	// 1) The call site will be bl x; nop (where the relocation
-	//    applies to the bl).  We rewrite this to bl x_stub; ld
-	//    r2,24(r1).  The ld is necessary because x_stub will save
-	//    r2 (the TOC pointer) at 24(r1) (the "TOC save slot").
-	//
-	// 2) We reserve space for a pointer in the .plt section (once
-	//    per referenced dynamic function).  .plt is a data
-	//    section filled solely by the dynamic linker (more like
-	//    .plt.got on other architectures).  Initially, the
-	//    dynamic linker will fill each slot with a pointer to the
-	//    corresponding x@plt entry point.
-	//
-	// 3) We generate the "call stub" x_stub (once per dynamic
-	//    function/object file pair).  This saves the TOC in the
-	//    TOC save slot, reads the function pointer from x's .plt
-	//    slot and calls it like any other global entry point
-	//    (including setting r12 to the function address).
-	//
-	// 4) We generate the "symbol resolver stub" x@plt (once per
-	//    dynamic function).  This is solely a branch to the glink
-	//    resolver stub.
-	//
-	// 5) We generate the glink resolver stub (only once).  This
-	//    computes which symbol resolver stub we came through and
-	//    invokes the dynamic resolver via a pointer provided by
-	//    the dynamic linker. This will patch up the .plt slot to
-	//    point directly at the function so future calls go
-	//    straight from the call stub to the real function, and
-	//    then call the function.
-
-	// NOTE: It's possible we could make ppc64 closer to other
-	// architectures: ppc64's .plt is like .plt.got on other
-	// platforms and ppc64's .glink is like .plt on other
-	// platforms.
-
-	// Find all R_PPC64_REL24 relocations that reference dynamic
-	// imports. Reserve PLT entries for these symbols and
-	// generate call stubs. The call stubs need to live in .text,
-	// which is why we need to do this pass this early.
-	//
-	// This assumes "case 1" from the ABI, where the caller needs
-	// us to save and restore the TOC pointer.
-	var stubs []*sym.Symbol
-	for _, s := range ctxt.Textp {
-		for i := range s.R {
-			r := &s.R[i]
-			if r.Type != objabi.ElfRelocOffset+objabi.RelocType(elf.R_PPC64_REL24) || r.Sym.Type != sym.SDYNIMPORT {
-				continue
-			}
-
-			// Reserve PLT entry and generate symbol
-			// resolver
-			addpltsym(ctxt, r.Sym)
-
-			// Generate call stub
-			n := fmt.Sprintf("%s.%s", s.Name, r.Sym.Name)
-
-			stub := ctxt.Syms.Lookup(n, 0)
-			if s.Attr.Reachable() {
-				stub.Attr |= sym.AttrReachable
-			}
-			if stub.Size == 0 {
-				// Need outer to resolve .TOC.
-				stub.Outer = s
-				stubs = append(stubs, stub)
-				gencallstub(ctxt, 1, stub, r.Sym)
-			}
-
-			// Update the relocation to use the call stub
-			r.Sym = stub
-
-			// Restore TOC after bl. The compiler put a
-			// nop here for us to overwrite.
-			const o1 = 0xe8410018 // ld r2,24(r1)
-			ctxt.Arch.ByteOrder.PutUint32(s.P[r.Off+4:], o1)
-		}
-	}
-	// Put call stubs at the beginning (instead of the end).
-	// So when resolving the relocations to calls to the stubs,
-	// the addresses are known and trampolines can be inserted
-	// when necessary.
-	ctxt.Textp = append(stubs, ctxt.Textp...)
-}
-
-func genaddmoduledata(ctxt *ld.Link) {
-	addmoduledata := ctxt.Syms.ROLookup("runtime.addmoduledata", sym.SymVerABI0)
-	if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
-		return
-	}
-	addmoduledata.Attr |= sym.AttrReachable
-	initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-	initfunc.Type = sym.STEXT
-	initfunc.Attr |= sym.AttrLocal
-	initfunc.Attr |= sym.AttrReachable
-	o := func(op uint32) {
-		initfunc.AddUint32(ctxt.Arch, op)
-	}
-	// addis r2, r12, .TOC.-func@ha
-	rel := initfunc.AddRel()
-	rel.Off = int32(initfunc.Size)
-	rel.Siz = 8
-	rel.Sym = ctxt.Syms.Lookup(".TOC.", 0)
-	rel.Sym.Attr |= sym.AttrReachable
-	rel.Type = objabi.R_ADDRPOWER_PCREL
-	o(0x3c4c0000)
-	// addi r2, r2, .TOC.-func@l
-	o(0x38420000)
-	// mflr r31
-	o(0x7c0802a6)
-	// stdu r31, -32(r1)
-	o(0xf801ffe1)
-	// addis r3, r2, local.moduledata@got@ha
-	rel = initfunc.AddRel()
-	rel.Off = int32(initfunc.Size)
-	rel.Siz = 8
-	if s := ctxt.Syms.ROLookup("local.moduledata", 0); s != nil {
-		rel.Sym = s
-	} else if s := ctxt.Syms.ROLookup("local.pluginmoduledata", 0); s != nil {
-		rel.Sym = s
-	} else {
-		rel.Sym = ctxt.Syms.Lookup("runtime.firstmoduledata", 0)
-	}
-	rel.Sym.Attr |= sym.AttrReachable
-	rel.Sym.Attr |= sym.AttrLocal
-	rel.Type = objabi.R_ADDRPOWER_GOT
-	o(0x3c620000)
-	// ld r3, local.moduledata@got@l(r3)
-	o(0xe8630000)
-	// bl runtime.addmoduledata
-	rel = initfunc.AddRel()
-	rel.Off = int32(initfunc.Size)
-	rel.Siz = 4
-	rel.Sym = addmoduledata
-	rel.Type = objabi.R_CALLPOWER
-	o(0x48000001)
-	// nop
-	o(0x60000000)
-	// ld r31, 0(r1)
-	o(0xe8010000)
-	// mtlr r31
-	o(0x7c0803a6)
-	// addi r1,r1,32
-	o(0x38210020)
-	// blr
-	o(0x4e800020)
-
-	if ctxt.BuildMode == ld.BuildModePlugin {
-		ctxt.Textp = append(ctxt.Textp, addmoduledata)
-	}
-	initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-	ctxt.Textp = append(ctxt.Textp, initfunc)
-	initarray_entry.Attr |= sym.AttrReachable
-	initarray_entry.Attr |= sym.AttrLocal
-	initarray_entry.Type = sym.SINITARR
-	initarray_entry.AddAddr(ctxt.Arch, initfunc)
-}
-
-func gentext(ctxt *ld.Link) {
-	if ctxt.DynlinkingGo() {
-		genaddmoduledata(ctxt)
-	}
-
-	if ctxt.LinkMode == ld.LinkInternal {
-		genplt(ctxt)
-	}
-}
-
-// Construct a call stub in stub that calls symbol targ via its PLT
-// entry.
-func gencallstub(ctxt *ld.Link, abicase int, stub *sym.Symbol, targ *sym.Symbol) {
-	if abicase != 1 {
-		// If we see R_PPC64_TOCSAVE or R_PPC64_REL24_NOTOC
-		// relocations, we'll need to implement cases 2 and 3.
-		log.Fatalf("gencallstub only implements case 1 calls")
-	}
-
-	plt := ctxt.Syms.Lookup(".plt", 0)
-
-	stub.Type = sym.STEXT
-
-	// Save TOC pointer in TOC save slot
-	stub.AddUint32(ctxt.Arch, 0xf8410018) // std r2,24(r1)
-
-	// Load the function pointer from the PLT.
-	r := stub.AddRel()
-
-	r.Off = int32(stub.Size)
-	r.Sym = plt
-	r.Add = int64(targ.Plt())
-	r.Siz = 2
-	if ctxt.Arch.ByteOrder == binary.BigEndian {
-		r.Off += int32(r.Siz)
-	}
-	r.Type = objabi.R_POWER_TOC
-	r.Variant = sym.RV_POWER_HA
-	stub.AddUint32(ctxt.Arch, 0x3d820000) // addis r12,r2,targ@plt@toc@ha
-	r = stub.AddRel()
-	r.Off = int32(stub.Size)
-	r.Sym = plt
-	r.Add = int64(targ.Plt())
-	r.Siz = 2
-	if ctxt.Arch.ByteOrder == binary.BigEndian {
-		r.Off += int32(r.Siz)
-	}
-	r.Type = objabi.R_POWER_TOC
-	r.Variant = sym.RV_POWER_LO
-	stub.AddUint32(ctxt.Arch, 0xe98c0000) // ld r12,targ@plt@toc@l(r12)
-
-	// Jump to the loaded pointer
-	stub.AddUint32(ctxt.Arch, 0x7d8903a6) // mtctr r12
-	stub.AddUint32(ctxt.Arch, 0x4e800420) // bctr
-}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-	if ctxt.IsELF {
-		return addelfdynrel(ctxt, s, r)
-	} else if ctxt.HeadType == objabi.Haix {
-		return ld.Xcoffadddynrel(ctxt, s, r)
-	}
-	return false
-}
-func addelfdynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-	targ := r.Sym
-	r.InitExt()
-
-	switch r.Type {
-	default:
-		if r.Type >= objabi.ElfRelocOffset {
-			ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
-			return false
-		}
-
-		// Handle relocations found in ELF object files.
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL24):
-		r.Type = objabi.R_CALLPOWER
-
-		// This is a local call, so the caller isn't setting
-		// up r12 and r2 is the same for the caller and
-		// callee. Hence, we need to go to the local entry
-		// point.  (If we don't do this, the callee will try
-		// to use r12 to compute r2.)
-		r.Add += int64(r.Sym.Localentry()) * 4
-
-		if targ.Type == sym.SDYNIMPORT {
-			// Should have been handled in elfsetupplt
-			ld.Errorf(s, "unexpected R_PPC64_REL24 for dyn import")
-		}
-
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC_REL32):
-		r.Type = objabi.R_PCREL
-		r.Add += 4
-
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected R_PPC_REL32 for dyn import")
-		}
-
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_ADDR64):
-		r.Type = objabi.R_ADDR
-		if targ.Type == sym.SDYNIMPORT {
-			// These happen in .toc sections
-			ld.Adddynsym(ctxt, targ)
-
-			rela := ctxt.Syms.Lookup(".rela", 0)
-			rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
-			rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_PPC64_ADDR64)))
-			rela.AddUint64(ctxt.Arch, uint64(r.Add))
-			r.Type = objabi.ElfRelocOffset // ignore during relocsym
-		}
-
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16):
-		r.Type = objabi.R_POWER_TOC
-		r.Variant = sym.RV_POWER_LO | sym.RV_CHECK_OVERFLOW
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_LO):
-		r.Type = objabi.R_POWER_TOC
-		r.Variant = sym.RV_POWER_LO
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_HA):
-		r.Type = objabi.R_POWER_TOC
-		r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_HI):
-		r.Type = objabi.R_POWER_TOC
-		r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_DS):
-		r.Type = objabi.R_POWER_TOC
-		r.Variant = sym.RV_POWER_DS | sym.RV_CHECK_OVERFLOW
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_LO_DS):
-		r.Type = objabi.R_POWER_TOC
-		r.Variant = sym.RV_POWER_DS
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL16_LO):
-		r.Type = objabi.R_PCREL
-		r.Variant = sym.RV_POWER_LO
-		r.Add += 2 // Compensate for relocation size of 2
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL16_HI):
-		r.Type = objabi.R_PCREL
-		r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW
-		r.Add += 2
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL16_HA):
-		r.Type = objabi.R_PCREL
-		r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW
-		r.Add += 2
-		return true
-	}
-
-	// Handle references to ELF symbols from our own object files.
-	if targ.Type != sym.SDYNIMPORT {
-		return true
-	}
-
-	// TODO(austin): Translate our relocations to ELF
-
-	return false
-}
-
-func xcoffreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-	rs := r.Xsym
-
-	emitReloc := func(v uint16, off uint64) {
-		out.Write64(uint64(sectoff) + off)
-		out.Write32(uint32(rs.Dynid))
-		out.Write16(v)
-	}
-
-	var v uint16
-	switch r.Type {
-	default:
-		return false
-	case objabi.R_ADDR:
-		v = ld.XCOFF_R_POS
-		if r.Siz == 4 {
-			v |= 0x1F << 8
-		} else {
-			v |= 0x3F << 8
-		}
-		emitReloc(v, 0)
-	case objabi.R_ADDRPOWER_TOCREL:
-	case objabi.R_ADDRPOWER_TOCREL_DS:
-		emitReloc(ld.XCOFF_R_TOCU|(0x0F<<8), 2)
-		emitReloc(ld.XCOFF_R_TOCL|(0x0F<<8), 6)
-	case objabi.R_POWER_TLS_LE:
-		emitReloc(ld.XCOFF_R_TLS_LE|0x0F<<8, 2)
-	case objabi.R_CALLPOWER:
-		if r.Siz != 4 {
-			return false
-		}
-		emitReloc(ld.XCOFF_R_RBR|0x19<<8, 0)
-	case objabi.R_XCOFFREF:
-		emitReloc(ld.XCOFF_R_REF|0x3F<<8, 0)
-
-	}
-	return true
-
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-	// Beware that bit0~bit15 start from the third byte of a instruction in Big-Endian machines.
-	if r.Type == objabi.R_ADDR || r.Type == objabi.R_POWER_TLS || r.Type == objabi.R_CALLPOWER {
-	} else {
-		if ctxt.Arch.ByteOrder == binary.BigEndian {
-			sectoff += 2
-		}
-	}
-	ctxt.Out.Write64(uint64(sectoff))
-
-	elfsym := r.Xsym.ElfsymForReloc()
-	switch r.Type {
-	default:
-		return false
-	case objabi.R_ADDR:
-		switch r.Siz {
-		case 4:
-			ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR32) | uint64(elfsym)<<32)
-		case 8:
-			ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR64) | uint64(elfsym)<<32)
-		default:
-			return false
-		}
-	case objabi.R_POWER_TLS:
-		ctxt.Out.Write64(uint64(elf.R_PPC64_TLS) | uint64(elfsym)<<32)
-	case objabi.R_POWER_TLS_LE:
-		ctxt.Out.Write64(uint64(elf.R_PPC64_TPREL16) | uint64(elfsym)<<32)
-	case objabi.R_POWER_TLS_IE:
-		ctxt.Out.Write64(uint64(elf.R_PPC64_GOT_TPREL16_HA) | uint64(elfsym)<<32)
-		ctxt.Out.Write64(uint64(r.Xadd))
-		ctxt.Out.Write64(uint64(sectoff + 4))
-		ctxt.Out.Write64(uint64(elf.R_PPC64_GOT_TPREL16_LO_DS) | uint64(elfsym)<<32)
-	case objabi.R_ADDRPOWER:
-		ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR16_HA) | uint64(elfsym)<<32)
-		ctxt.Out.Write64(uint64(r.Xadd))
-		ctxt.Out.Write64(uint64(sectoff + 4))
-		ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR16_LO) | uint64(elfsym)<<32)
-	case objabi.R_ADDRPOWER_DS:
-		ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR16_HA) | uint64(elfsym)<<32)
-		ctxt.Out.Write64(uint64(r.Xadd))
-		ctxt.Out.Write64(uint64(sectoff + 4))
-		ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR16_LO_DS) | uint64(elfsym)<<32)
-	case objabi.R_ADDRPOWER_GOT:
-		ctxt.Out.Write64(uint64(elf.R_PPC64_GOT16_HA) | uint64(elfsym)<<32)
-		ctxt.Out.Write64(uint64(r.Xadd))
-		ctxt.Out.Write64(uint64(sectoff + 4))
-		ctxt.Out.Write64(uint64(elf.R_PPC64_GOT16_LO_DS) | uint64(elfsym)<<32)
-	case objabi.R_ADDRPOWER_PCREL:
-		ctxt.Out.Write64(uint64(elf.R_PPC64_REL16_HA) | uint64(elfsym)<<32)
-		ctxt.Out.Write64(uint64(r.Xadd))
-		ctxt.Out.Write64(uint64(sectoff + 4))
-		ctxt.Out.Write64(uint64(elf.R_PPC64_REL16_LO) | uint64(elfsym)<<32)
-		r.Xadd += 4
-	case objabi.R_ADDRPOWER_TOCREL:
-		ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_HA) | uint64(elfsym)<<32)
-		ctxt.Out.Write64(uint64(r.Xadd))
-		ctxt.Out.Write64(uint64(sectoff + 4))
-		ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_LO) | uint64(elfsym)<<32)
-	case objabi.R_ADDRPOWER_TOCREL_DS:
-		ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_HA) | uint64(elfsym)<<32)
-		ctxt.Out.Write64(uint64(r.Xadd))
-		ctxt.Out.Write64(uint64(sectoff + 4))
-		ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_LO_DS) | uint64(elfsym)<<32)
-	case objabi.R_CALLPOWER:
-		if r.Siz != 4 {
-			return false
-		}
-		ctxt.Out.Write64(uint64(elf.R_PPC64_REL24) | uint64(elfsym)<<32)
-
-	}
-	ctxt.Out.Write64(uint64(r.Xadd))
-
-	return true
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-	plt := ctxt.Syms.Lookup(".plt", 0)
-	if plt.Size == 0 {
-		// The dynamic linker stores the address of the
-		// dynamic resolver and the DSO identifier in the two
-		// doublewords at the beginning of the .plt section
-		// before the PLT array. Reserve space for these.
-		plt.Size = 16
-	}
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-	return false
-}
-
-// Return the value of .TOC. for symbol s
-func symtoc(ctxt *ld.Link, s *sym.Symbol) int64 {
-	var toc *sym.Symbol
-
-	if s.Outer != nil {
-		toc = ctxt.Syms.ROLookup(".TOC.", int(s.Outer.Version))
-	} else {
-		toc = ctxt.Syms.ROLookup(".TOC.", int(s.Version))
-	}
-
-	if toc == nil {
-		ld.Errorf(s, "TOC-relative relocation in object without .TOC.")
-		return 0
-	}
-
-	return toc.Value
-}
-
-// archreloctoc relocates a TOC relative symbol.
-// If the symbol pointed by this TOC relative symbol is in .data or .bss, the
-// default load instruction can be changed to an addi instruction and the
-// symbol address can be used directly.
-// This code is for AIX only.
-func archreloctoc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) int64 {
-	if ctxt.HeadType == objabi.Hlinux {
-		ld.Errorf(s, "archrelocaddr called for %s relocation\n", r.Sym.Name)
-	}
-	var o1, o2 uint32
-
-	o1 = uint32(val >> 32)
-	o2 = uint32(val)
-
-	var t int64
-	useAddi := false
-	const prefix = "TOC."
-	var tarSym *sym.Symbol
-	if strings.HasPrefix(r.Sym.Name, prefix) {
-		tarSym = r.Sym.R[0].Sym
-	} else {
-		ld.Errorf(s, "archreloctoc called for a symbol without TOC anchor")
-	}
-
-	if ctxt.LinkMode == ld.LinkInternal && tarSym != nil && tarSym.Attr.Reachable() && (tarSym.Sect.Seg == &ld.Segdata) {
-		t = ld.Symaddr(tarSym) + r.Add - ctxt.Syms.ROLookup("TOC", 0).Value
-		// change ld to addi in the second instruction
-		o2 = (o2 & 0x03FF0000) | 0xE<<26
-		useAddi = true
-	} else {
-		t = ld.Symaddr(r.Sym) + r.Add - ctxt.Syms.ROLookup("TOC", 0).Value
-	}
-
-	if t != int64(int32(t)) {
-		ld.Errorf(s, "TOC relocation for %s is too big to relocate %s: 0x%x", s.Name, r.Sym, t)
-	}
-
-	if t&0x8000 != 0 {
-		t += 0x10000
-	}
-
-	o1 |= uint32((t >> 16) & 0xFFFF)
-
-	switch r.Type {
-	case objabi.R_ADDRPOWER_TOCREL_DS:
-		if useAddi {
-			o2 |= uint32(t) & 0xFFFF
-		} else {
-			if t&3 != 0 {
-				ld.Errorf(s, "bad DS reloc for %s: %d", s.Name, ld.Symaddr(r.Sym))
-			}
-			o2 |= uint32(t) & 0xFFFC
-		}
-	default:
-		return -1
-	}
-
-	return int64(o1)<<32 | int64(o2)
-}
-
-// archrelocaddr relocates a symbol address.
-// This code is for AIX only.
-func archrelocaddr(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) int64 {
-	if ctxt.HeadType == objabi.Haix {
-		ld.Errorf(s, "archrelocaddr called for %s relocation\n", r.Sym.Name)
-	}
-	var o1, o2 uint32
-	if ctxt.Arch.ByteOrder == binary.BigEndian {
-		o1 = uint32(val >> 32)
-		o2 = uint32(val)
-	} else {
-		o1 = uint32(val)
-		o2 = uint32(val >> 32)
-	}
-
-	// We are spreading a 31-bit address across two instructions, putting the
-	// high (adjusted) part in the low 16 bits of the first instruction and the
-	// low part in the low 16 bits of the second instruction, or, in the DS case,
-	// bits 15-2 (inclusive) of the address into bits 15-2 of the second
-	// instruction (it is an error in this case if the low 2 bits of the address
-	// are non-zero).
-
-	t := ld.Symaddr(r.Sym) + r.Add
-	if t < 0 || t >= 1<<31 {
-		ld.Errorf(s, "relocation for %s is too big (>=2G): 0x%x", s.Name, ld.Symaddr(r.Sym))
-	}
-	if t&0x8000 != 0 {
-		t += 0x10000
-	}
-
-	switch r.Type {
-	case objabi.R_ADDRPOWER:
-		o1 |= (uint32(t) >> 16) & 0xffff
-		o2 |= uint32(t) & 0xffff
-	case objabi.R_ADDRPOWER_DS:
-		o1 |= (uint32(t) >> 16) & 0xffff
-		if t&3 != 0 {
-			ld.Errorf(s, "bad DS reloc for %s: %d", s.Name, ld.Symaddr(r.Sym))
-		}
-		o2 |= uint32(t) & 0xfffc
-	default:
-		return -1
-	}
-
-	if ctxt.Arch.ByteOrder == binary.BigEndian {
-		return int64(o1)<<32 | int64(o2)
-	}
-	return int64(o2)<<32 | int64(o1)
-}
-
-// resolve direct jump relocation r in s, and add trampoline if necessary
-func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
-
-	// Trampolines are created if the branch offset is too large and the linker cannot insert a call stub to handle it.
-	// For internal linking, trampolines are always created for long calls.
-	// For external linking, the linker can insert a call stub to handle a long call, but depends on having the TOC address in
-	// r2.  For those build modes with external linking where the TOC address is not maintained in r2, trampolines must be created.
-	if ctxt.LinkMode == ld.LinkExternal && (ctxt.DynlinkingGo() || ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE) {
-		// No trampolines needed since r2 contains the TOC
-		return
-	}
-
-	t := ld.Symaddr(r.Sym) + r.Add - (s.Value + int64(r.Off))
-	switch r.Type {
-	case objabi.R_CALLPOWER:
-
-		// If branch offset is too far then create a trampoline.
-
-		if (ctxt.LinkMode == ld.LinkExternal && s.Sect != r.Sym.Sect) || (ctxt.LinkMode == ld.LinkInternal && int64(int32(t<<6)>>6) != t) || (*ld.FlagDebugTramp > 1 && s.File != r.Sym.File) {
-			var tramp *sym.Symbol
-			for i := 0; ; i++ {
-
-				// Using r.Add as part of the name is significant in functions like duffzero where the call
-				// target is at some offset within the function.  Calls to duff+8 and duff+256 must appear as
-				// distinct trampolines.
-
-				name := r.Sym.Name
-				if r.Add == 0 {
-					name = name + fmt.Sprintf("-tramp%d", i)
-				} else {
-					name = name + fmt.Sprintf("%+x-tramp%d", r.Add, i)
-				}
-
-				// Look up the trampoline in case it already exists
-
-				tramp = ctxt.Syms.Lookup(name, int(r.Sym.Version))
-				if tramp.Value == 0 {
-					break
-				}
-
-				t = ld.Symaddr(tramp) + r.Add - (s.Value + int64(r.Off))
-
-				// With internal linking, the trampoline can be used if it is not too far.
-				// With external linking, the trampoline must be in this section for it to be reused.
-				if (ctxt.LinkMode == ld.LinkInternal && int64(int32(t<<6)>>6) == t) || (ctxt.LinkMode == ld.LinkExternal && s.Sect == tramp.Sect) {
-					break
-				}
-			}
-			if tramp.Type == 0 {
-				if ctxt.DynlinkingGo() || ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE {
-					// Should have returned for above cases
-					ld.Errorf(s, "unexpected trampoline for shared or dynamic linking\n")
-				} else {
-					ctxt.AddTramp(tramp)
-					gentramp(ctxt, tramp, r.Sym, r.Add)
-				}
-			}
-			r.Sym = tramp
-			r.Add = 0 // This was folded into the trampoline target address
-			r.Done = false
-		}
-	default:
-		ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
-	}
-}
-
-func gentramp(ctxt *ld.Link, tramp, target *sym.Symbol, offset int64) {
-	tramp.Size = 16 // 4 instructions
-	tramp.P = make([]byte, tramp.Size)
-	t := ld.Symaddr(target) + offset
-	var o1, o2 uint32
-
-	if ctxt.HeadType == objabi.Haix {
-		// On AIX, the address is retrieved with a TOC symbol.
-		// For internal linking, the "Linux" way might still be used.
-		// However, all text symbols are accessed with a TOC symbol as
-		// text relocations aren't supposed to be possible.
-		// So, keep using the external linking way to be more AIX friendly.
-		o1 = uint32(0x3fe20000) // lis r2, toctargetaddr hi
-		o2 = uint32(0xebff0000) // ld r31, toctargetaddr lo
-
-		toctramp := ctxt.Syms.Lookup("TOC."+tramp.Name, 0)
-		toctramp.Type = sym.SXCOFFTOC
-		toctramp.Attr |= sym.AttrReachable
-		toctramp.AddAddr(ctxt.Arch, target)
-
-		tr := tramp.AddRel()
-		tr.Off = 0
-		tr.Type = objabi.R_ADDRPOWER_TOCREL_DS
-		tr.Siz = 8 // generates 2 relocations:  HA + LO
-		tr.Sym = toctramp
-		tr.Add = offset
-	} else {
-		// Used for default build mode for an executable
-		// Address of the call target is generated using
-		// relocation and doesn't depend on r2 (TOC).
-		o1 = uint32(0x3fe00000) // lis r31,targetaddr hi
-		o2 = uint32(0x3bff0000) // addi r31,targetaddr lo
-
-		// With external linking, the target address must be
-		// relocated using LO and HA
-		if ctxt.LinkMode == ld.LinkExternal {
-			tr := tramp.AddRel()
-			tr.Off = 0
-			tr.Type = objabi.R_ADDRPOWER
-			tr.Siz = 8 // generates 2 relocations:  HA + LO
-			tr.Sym = target
-			tr.Add = offset
-
-		} else {
-			// adjustment needed if lo has sign bit set
-			// when using addi to compute address
-			val := uint32((t & 0xffff0000) >> 16)
-			if t&0x8000 != 0 {
-				val += 1
-			}
-			o1 |= val                // hi part of addr
-			o2 |= uint32(t & 0xffff) // lo part of addr
-		}
-	}
-
-	o3 := uint32(0x7fe903a6) // mtctr r31
-	o4 := uint32(0x4e800420) // bctr
-	ctxt.Arch.ByteOrder.PutUint32(tramp.P, o1)
-	ctxt.Arch.ByteOrder.PutUint32(tramp.P[4:], o2)
-	ctxt.Arch.ByteOrder.PutUint32(tramp.P[8:], o3)
-	ctxt.Arch.ByteOrder.PutUint32(tramp.P[12:], o4)
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-	if ctxt.LinkMode == ld.LinkExternal {
-		// On AIX, relocations (except TLS ones) must be also done to the
-		// value with the current addresses.
-		switch r.Type {
-		default:
-			if ctxt.HeadType != objabi.Haix {
-				return val, false
-			}
-		case objabi.R_POWER_TLS, objabi.R_POWER_TLS_LE, objabi.R_POWER_TLS_IE:
-			r.Done = false
-			// check Outer is nil, Type is TLSBSS?
-			r.Xadd = r.Add
-			r.Xsym = r.Sym
-			return val, true
-		case objabi.R_ADDRPOWER,
-			objabi.R_ADDRPOWER_DS,
-			objabi.R_ADDRPOWER_TOCREL,
-			objabi.R_ADDRPOWER_TOCREL_DS,
-			objabi.R_ADDRPOWER_GOT,
-			objabi.R_ADDRPOWER_PCREL:
-			r.Done = false
-
-			// set up addend for eventual relocation via outer symbol.
-			rs := r.Sym
-			r.Xadd = r.Add
-			for rs.Outer != nil {
-				r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
-				rs = rs.Outer
-			}
-
-			if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Type != sym.SUNDEFEXT && rs.Sect == nil {
-				ld.Errorf(s, "missing section for %s", rs.Name)
-			}
-			r.Xsym = rs
-
-			if ctxt.HeadType != objabi.Haix {
-				return val, true
-			}
-		case objabi.R_CALLPOWER:
-			r.Done = false
-			r.Xsym = r.Sym
-			r.Xadd = r.Add
-			if ctxt.HeadType != objabi.Haix {
-				return val, true
-			}
-		}
-	}
-
-	switch r.Type {
-	case objabi.R_CONST:
-		return r.Add, true
-	case objabi.R_GOTOFF:
-		return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
-	case objabi.R_ADDRPOWER_TOCREL, objabi.R_ADDRPOWER_TOCREL_DS:
-		return archreloctoc(ctxt, r, s, val), true
-	case objabi.R_ADDRPOWER, objabi.R_ADDRPOWER_DS:
-		return archrelocaddr(ctxt, r, s, val), true
-	case objabi.R_CALLPOWER:
-		// Bits 6 through 29 = (S + A - P) >> 2
-
-		t := ld.Symaddr(r.Sym) + r.Add - (s.Value + int64(r.Off))
-
-		if t&3 != 0 {
-			ld.Errorf(s, "relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
-		}
-		// If branch offset is too far then create a trampoline.
-
-		if int64(int32(t<<6)>>6) != t {
-			ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
-		}
-		return val | int64(uint32(t)&^0xfc000003), true
-	case objabi.R_POWER_TOC: // S + A - .TOC.
-		return ld.Symaddr(r.Sym) + r.Add - symtoc(ctxt, s), true
-
-	case objabi.R_POWER_TLS_LE:
-		// The thread pointer points 0x7000 bytes after the start of the
-		// thread local storage area as documented in section "3.7.2 TLS
-		// Runtime Handling" of "Power Architecture 64-Bit ELF V2 ABI
-		// Specification".
-		v := r.Sym.Value - 0x7000
-		if ctxt.HeadType == objabi.Haix {
-			// On AIX, the thread pointer points 0x7800 bytes after
-			// the TLS.
-			v -= 0x800
-		}
-		if int64(int16(v)) != v {
-			ld.Errorf(s, "TLS offset out of range %d", v)
-		}
-		return (val &^ 0xffff) | (v & 0xffff), true
-	}
-
-	return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-	switch r.Variant & sym.RV_TYPE_MASK {
-	default:
-		ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
-		fallthrough
-
-	case sym.RV_NONE:
-		return t
-
-	case sym.RV_POWER_LO:
-		if r.Variant&sym.RV_CHECK_OVERFLOW != 0 {
-			// Whether to check for signed or unsigned
-			// overflow depends on the instruction
-			var o1 uint32
-			if ctxt.Arch.ByteOrder == binary.BigEndian {
-				o1 = binary.BigEndian.Uint32(s.P[r.Off-2:])
-			} else {
-				o1 = binary.LittleEndian.Uint32(s.P[r.Off:])
-			}
-			switch o1 >> 26 {
-			case 24, // ori
-				26, // xori
-				28: // andi
-				if t>>16 != 0 {
-					goto overflow
-				}
-
-			default:
-				if int64(int16(t)) != t {
-					goto overflow
-				}
-			}
-		}
-
-		return int64(int16(t))
-
-	case sym.RV_POWER_HA:
-		t += 0x8000
-		fallthrough
-
-		// Fallthrough
-	case sym.RV_POWER_HI:
-		t >>= 16
-
-		if r.Variant&sym.RV_CHECK_OVERFLOW != 0 {
-			// Whether to check for signed or unsigned
-			// overflow depends on the instruction
-			var o1 uint32
-			if ctxt.Arch.ByteOrder == binary.BigEndian {
-				o1 = binary.BigEndian.Uint32(s.P[r.Off-2:])
-			} else {
-				o1 = binary.LittleEndian.Uint32(s.P[r.Off:])
-			}
-			switch o1 >> 26 {
-			case 25, // oris
-				27, // xoris
-				29: // andis
-				if t>>16 != 0 {
-					goto overflow
-				}
-
-			default:
-				if int64(int16(t)) != t {
-					goto overflow
-				}
-			}
-		}
-
-		return int64(int16(t))
-
-	case sym.RV_POWER_DS:
-		var o1 uint32
-		if ctxt.Arch.ByteOrder == binary.BigEndian {
-			o1 = uint32(binary.BigEndian.Uint16(s.P[r.Off:]))
-		} else {
-			o1 = uint32(binary.LittleEndian.Uint16(s.P[r.Off:]))
-		}
-		if t&3 != 0 {
-			ld.Errorf(s, "relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
-		}
-		if (r.Variant&sym.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t {
-			goto overflow
-		}
-		return int64(o1)&0x3 | int64(int16(t))
-	}
-
-overflow:
-	ld.Errorf(s, "relocation for %s+%d is too big: %d", r.Sym.Name, r.Off, t)
-	return t
-}
-
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
-	if s.Plt() >= 0 {
-		return
-	}
-
-	ld.Adddynsym(ctxt, s)
-
-	if ctxt.IsELF {
-		plt := ctxt.Syms.Lookup(".plt", 0)
-		rela := ctxt.Syms.Lookup(".rela.plt", 0)
-		if plt.Size == 0 {
-			elfsetupplt(ctxt)
-		}
-
-		// Create the glink resolver if necessary
-		glink := ensureglinkresolver(ctxt)
-
-		// Write symbol resolver stub (just a branch to the
-		// glink resolver stub)
-		r := glink.AddRel()
-
-		r.Sym = glink
-		r.Off = int32(glink.Size)
-		r.Siz = 4
-		r.Type = objabi.R_CALLPOWER
-		glink.AddUint32(ctxt.Arch, 0x48000000) // b .glink
-
-		// In the ppc64 ABI, the dynamic linker is responsible
-		// for writing the entire PLT.  We just need to
-		// reserve 8 bytes for each PLT entry and generate a
-		// JMP_SLOT dynamic relocation for it.
-		//
-		// TODO(austin): ABI v1 is different
-		s.SetPlt(int32(plt.Size))
-
-		plt.Size += 8
-
-		rela.AddAddrPlus(ctxt.Arch, plt, int64(s.Plt()))
-		rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_PPC64_JMP_SLOT)))
-		rela.AddUint64(ctxt.Arch, 0)
-	} else {
-		ld.Errorf(s, "addpltsym: unsupported binary format")
-	}
-}
-
-// Generate the glink resolver stub if necessary and return the .glink section
-func ensureglinkresolver(ctxt *ld.Link) *sym.Symbol {
-	glink := ctxt.Syms.Lookup(".glink", 0)
-	if glink.Size != 0 {
-		return glink
-	}
-
-	// This is essentially the resolver from the ppc64 ELF ABI.
-	// At entry, r12 holds the address of the symbol resolver stub
-	// for the target routine and the argument registers hold the
-	// arguments for the target routine.
-	//
-	// This stub is PIC, so first get the PC of label 1 into r11.
-	// Other things will be relative to this.
-	glink.AddUint32(ctxt.Arch, 0x7c0802a6) // mflr r0
-	glink.AddUint32(ctxt.Arch, 0x429f0005) // bcl 20,31,1f
-	glink.AddUint32(ctxt.Arch, 0x7d6802a6) // 1: mflr r11
-	glink.AddUint32(ctxt.Arch, 0x7c0803a6) // mtlf r0
-
-	// Compute the .plt array index from the entry point address.
-	// Because this is PIC, everything is relative to label 1b (in
-	// r11):
-	//   r0 = ((r12 - r11) - (res_0 - r11)) / 4 = (r12 - res_0) / 4
-	glink.AddUint32(ctxt.Arch, 0x3800ffd0) // li r0,-(res_0-1b)=-48
-	glink.AddUint32(ctxt.Arch, 0x7c006214) // add r0,r0,r12
-	glink.AddUint32(ctxt.Arch, 0x7c0b0050) // sub r0,r0,r11
-	glink.AddUint32(ctxt.Arch, 0x7800f082) // srdi r0,r0,2
-
-	// r11 = address of the first byte of the PLT
-	r := glink.AddRel()
-
-	r.Off = int32(glink.Size)
-	r.Sym = ctxt.Syms.Lookup(".plt", 0)
-	r.Siz = 8
-	r.Type = objabi.R_ADDRPOWER
-
-	glink.AddUint32(ctxt.Arch, 0x3d600000) // addis r11,0,.plt@ha
-	glink.AddUint32(ctxt.Arch, 0x396b0000) // addi r11,r11,.plt@l
-
-	// Load r12 = dynamic resolver address and r11 = DSO
-	// identifier from the first two doublewords of the PLT.
-	glink.AddUint32(ctxt.Arch, 0xe98b0000) // ld r12,0(r11)
-	glink.AddUint32(ctxt.Arch, 0xe96b0008) // ld r11,8(r11)
-
-	// Jump to the dynamic resolver
-	glink.AddUint32(ctxt.Arch, 0x7d8903a6) // mtctr r12
-	glink.AddUint32(ctxt.Arch, 0x4e800420) // bctr
-
-	// The symbol resolvers must immediately follow.
-	//   res_0:
-
-	// Add DT_PPC64_GLINK .dynamic entry, which points to 32 bytes
-	// before the first symbol resolver stub.
-	s := ctxt.Syms.Lookup(".dynamic", 0)
-
-	ld.Elfwritedynentsymplus(ctxt, s, ld.DT_PPC64_GLINK, glink, glink.Size-32)
-
-	return glink
-}
-
-func asmb(ctxt *ld.Link) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	for _, sect := range ld.Segtext.Sections {
-		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-		// Handle additional text sections with Codeblk
-		if sect.Name == ".text" {
-			ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-		} else {
-			ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-		}
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-	}
-	if ld.Segrelrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
-	}
-
-	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-	/* output symbol table */
-	ld.Symsize = 0
-
-	ld.Lcsize = 0
-	symo := uint32(0)
-	if !*ld.FlagS {
-		// TODO: rationalize
-		switch ctxt.HeadType {
-		default:
-			if ctxt.IsELF {
-				symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-				symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
-			}
-
-		case objabi.Hplan9:
-			symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
-
-		case objabi.Haix:
-			// Nothing to do
-		}
-
-		ctxt.Out.SeekSet(int64(symo))
-		switch ctxt.HeadType {
-		default:
-			if ctxt.IsELF {
-				ld.Asmelfsym(ctxt)
-				ctxt.Out.Flush()
-				ctxt.Out.Write(ld.Elfstrdat)
-
-				if ctxt.LinkMode == ld.LinkExternal {
-					ld.Elfemitreloc(ctxt)
-				}
-			}
-
-		case objabi.Hplan9:
-			ld.Asmplan9sym(ctxt)
-			ctxt.Out.Flush()
-
-			sym := ctxt.Syms.Lookup("pclntab", 0)
-			if sym != nil {
-				ld.Lcsize = int32(len(sym.P))
-				ctxt.Out.Write(sym.P)
-				ctxt.Out.Flush()
-			}
-
-		case objabi.Haix:
-			// symtab must be added once sections have been created in ld.Asmbxcoff
-			ctxt.Out.Flush()
-		}
-	}
-
-	ctxt.Out.SeekSet(0)
-	switch ctxt.HeadType {
-	default:
-	case objabi.Hplan9: /* plan 9 */
-		ctxt.Out.Write32(0x647)                      /* magic */
-		ctxt.Out.Write32(uint32(ld.Segtext.Filelen)) /* sizes */
-		ctxt.Out.Write32(uint32(ld.Segdata.Filelen))
-		ctxt.Out.Write32(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-		ctxt.Out.Write32(uint32(ld.Symsize))          /* nsyms */
-		ctxt.Out.Write32(uint32(ld.Entryvalue(ctxt))) /* va of entry */
-		ctxt.Out.Write32(0)
-		ctxt.Out.Write32(uint32(ld.Lcsize))
-
-	case objabi.Hlinux,
-		objabi.Hfreebsd,
-		objabi.Hnetbsd,
-		objabi.Hopenbsd:
-		ld.Asmbelf(ctxt, int64(symo))
-
-	case objabi.Haix:
-		fileoff := uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-		fileoff = uint32(ld.Rnd(int64(fileoff), int64(*ld.FlagRound)))
-		ld.Asmbxcoff(ctxt, int64(fileoff))
-	}
-
-	ctxt.Out.Flush()
-	if *ld.FlagC {
-		fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
-		fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
-		fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
-		fmt.Printf("symsize=%d\n", ld.Symsize)
-		fmt.Printf("lcsize=%d\n", ld.Lcsize)
-		fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
-	}
-}
diff --git a/src/cmd/oldlink/internal/ppc64/l.go b/src/cmd/oldlink/internal/ppc64/l.go
deleted file mode 100644
index c78535b..0000000
--- a/src/cmd/oldlink/internal/ppc64/l.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ppc64
-
-// Writing object files.
-
-// cmd/9l/l.h from Vita Nuova.
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-const (
-	maxAlign  = 32 // max data alignment
-	minAlign  = 1  // min data alignment
-	funcAlign = 16
-)
-
-/* Used by ../internal/ld/dwarf.go */
-const (
-	dwarfRegSP = 1
-	dwarfRegLR = 65
-)
diff --git a/src/cmd/oldlink/internal/ppc64/obj.go b/src/cmd/oldlink/internal/ppc64/obj.go
deleted file mode 100644
index e9da5a3..0000000
--- a/src/cmd/oldlink/internal/ppc64/obj.go
+++ /dev/null
@@ -1,106 +0,0 @@
-// Inferno utils/5l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/obj.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ppc64
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-	arch := sys.ArchPPC64
-	if objabi.GOARCH == "ppc64le" {
-		arch = sys.ArchPPC64LE
-	}
-
-	theArch := ld.Arch{
-		Funcalign:  funcAlign,
-		Maxalign:   maxAlign,
-		Minalign:   minAlign,
-		Dwarfregsp: dwarfRegSP,
-		Dwarfreglr: dwarfRegLR,
-
-		Adddynrel:        adddynrel,
-		Archinit:         archinit,
-		Archreloc:        archreloc,
-		Archrelocvariant: archrelocvariant,
-		Asmb:             asmb,
-		Asmb2:            asmb2,
-		Elfreloc1:        elfreloc1,
-		Elfsetupplt:      elfsetupplt,
-		Gentext:          gentext,
-		Trampoline:       trampoline,
-		Machoreloc1:      machoreloc1,
-		Xcoffreloc1:      xcoffreloc1,
-
-		// TODO(austin): ABI v1 uses /usr/lib/ld.so.1,
-		Linuxdynld: "/lib64/ld64.so.1",
-
-		Freebsddynld:   "XXX",
-		Openbsddynld:   "XXX",
-		Netbsddynld:    "XXX",
-		Dragonflydynld: "XXX",
-		Solarisdynld:   "XXX",
-	}
-
-	return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-	switch ctxt.HeadType {
-	default:
-		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-
-	case objabi.Hplan9: /* plan 9 */
-		ld.HEADR = 32
-
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 4128
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 4096
-		}
-
-	case objabi.Hlinux: /* ppc64 elf */
-		ld.Elfinit(ctxt)
-		ld.HEADR = ld.ELFRESERVE
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 0x10000
-		}
-
-	case objabi.Haix:
-		ld.Xcoffinit(ctxt)
-	}
-}
diff --git a/src/cmd/oldlink/internal/riscv64/asm.go b/src/cmd/oldlink/internal/riscv64/asm.go
deleted file mode 100644
index f4db32d..0000000
--- a/src/cmd/oldlink/internal/riscv64/asm.go
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2019 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 riscv64
-
-import (
-	"cmd/internal/obj/riscv"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-	"cmd/oldlink/internal/sym"
-	"fmt"
-	"log"
-)
-
-func gentext(ctxt *ld.Link) {
-}
-
-func adddynrela(ctxt *ld.Link, rel *sym.Symbol, s *sym.Symbol, r *sym.Reloc) {
-	log.Fatalf("adddynrela not implemented")
-}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-	log.Fatalf("adddynrel not implemented")
-	return false
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-	log.Fatalf("elfreloc1")
-	return false
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-	log.Fatalf("elfsetuplt")
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-	log.Fatalf("machoreloc1 not implemented")
-	return false
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-	switch r.Type {
-	case objabi.R_CALLRISCV:
-		// Nothing to do.
-		return val, true
-
-	case objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE:
-		pc := s.Value + int64(r.Off)
-		off := ld.Symaddr(r.Sym) + r.Add - pc
-
-		// Generate AUIPC and second instruction immediates.
-		low, high, err := riscv.Split32BitImmediate(off)
-		if err != nil {
-			ld.Errorf(s, "R_RISCV_PCREL_ relocation does not fit in 32-bits: %d", off)
-		}
-
-		auipcImm, err := riscv.EncodeUImmediate(high)
-		if err != nil {
-			ld.Errorf(s, "cannot encode R_RISCV_PCREL_ AUIPC relocation offset for %s: %v", r.Sym.Name, err)
-		}
-
-		var secondImm, secondImmMask int64
-		switch r.Type {
-		case objabi.R_RISCV_PCREL_ITYPE:
-			secondImmMask = riscv.ITypeImmMask
-			secondImm, err = riscv.EncodeIImmediate(low)
-			if err != nil {
-				ld.Errorf(s, "cannot encode R_RISCV_PCREL_ITYPE I-type instruction relocation offset for %s: %v", r.Sym.Name, err)
-			}
-		case objabi.R_RISCV_PCREL_STYPE:
-			secondImmMask = riscv.STypeImmMask
-			secondImm, err = riscv.EncodeSImmediate(low)
-			if err != nil {
-				ld.Errorf(s, "cannot encode R_RISCV_PCREL_STYPE S-type instruction relocation offset for %s: %v", r.Sym.Name, err)
-			}
-		default:
-			panic(fmt.Sprintf("Unknown relocation type: %v", r.Type))
-		}
-
-		auipc := int64(uint32(val))
-		second := int64(uint32(val >> 32))
-
-		auipc = (auipc &^ riscv.UTypeImmMask) | int64(uint32(auipcImm))
-		second = (second &^ secondImmMask) | int64(uint32(secondImm))
-
-		return second<<32 | auipc, true
-	}
-
-	return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-	log.Fatalf("archrelocvariant")
-	return -1
-}
-
-func asmb(ctxt *ld.Link) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	sect := ld.Segtext.Sections[0]
-	ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-	ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-	for _, sect = range ld.Segtext.Sections[1:] {
-		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-		ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-	}
-	if ld.Segrelrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
-	}
-
-	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-	ld.Symsize = 0
-	ld.Lcsize = 0
-	symo := uint32(0)
-
-	if !*ld.FlagS {
-		if !ctxt.IsELF {
-			ld.Errorf(nil, "unsupported executable format")
-		}
-
-		symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-		symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
-		ctxt.Out.SeekSet(int64(symo))
-
-		ld.Asmelfsym(ctxt)
-		ctxt.Out.Flush()
-		ctxt.Out.Write(ld.Elfstrdat)
-
-		if ctxt.LinkMode == ld.LinkExternal {
-			ld.Elfemitreloc(ctxt)
-		}
-	}
-
-	ctxt.Out.SeekSet(0)
-	switch ctxt.HeadType {
-	case objabi.Hlinux:
-		ld.Asmbelf(ctxt, int64(symo))
-	default:
-		ld.Errorf(nil, "unsupported operating system")
-	}
-	ctxt.Out.Flush()
-
-	if *ld.FlagC {
-		fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
-		fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
-		fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
-		fmt.Printf("symsize=%d\n", ld.Symsize)
-		fmt.Printf("lcsize=%d\n", ld.Lcsize)
-		fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
-	}
-}
diff --git a/src/cmd/oldlink/internal/riscv64/l.go b/src/cmd/oldlink/internal/riscv64/l.go
deleted file mode 100644
index a302657..0000000
--- a/src/cmd/oldlink/internal/riscv64/l.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2019 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 riscv64
-
-const (
-	maxAlign  = 32 // max data alignment
-	minAlign  = 1
-	funcAlign = 8
-
-	dwarfRegLR = 1
-	dwarfRegSP = 2
-)
diff --git a/src/cmd/oldlink/internal/riscv64/obj.go b/src/cmd/oldlink/internal/riscv64/obj.go
deleted file mode 100644
index a6a5adb..0000000
--- a/src/cmd/oldlink/internal/riscv64/obj.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2019 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 riscv64
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-	arch := sys.ArchRISCV64
-
-	theArch := ld.Arch{
-		Funcalign:  funcAlign,
-		Maxalign:   maxAlign,
-		Minalign:   minAlign,
-		Dwarfregsp: dwarfRegSP,
-		Dwarfreglr: dwarfRegLR,
-
-		Adddynrel:        adddynrel,
-		Archinit:         archinit,
-		Archreloc:        archreloc,
-		Archrelocvariant: archrelocvariant,
-		Asmb:             asmb,
-		Asmb2:            asmb2,
-		Elfreloc1:        elfreloc1,
-		Elfsetupplt:      elfsetupplt,
-		Gentext:          gentext,
-		Machoreloc1:      machoreloc1,
-
-		Linuxdynld: "/lib/ld.so.1",
-
-		Freebsddynld:   "XXX",
-		Netbsddynld:    "XXX",
-		Openbsddynld:   "XXX",
-		Dragonflydynld: "XXX",
-		Solarisdynld:   "XXX",
-	}
-
-	return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-	switch ctxt.HeadType {
-	case objabi.Hlinux:
-		ld.Elfinit(ctxt)
-		ld.HEADR = ld.ELFRESERVE
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 0x10000
-		}
-	default:
-		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-	}
-}
diff --git a/src/cmd/oldlink/internal/s390x/asm.go b/src/cmd/oldlink/internal/s390x/asm.go
deleted file mode 100644
index 6c5744d..0000000
--- a/src/cmd/oldlink/internal/s390x/asm.go
+++ /dev/null
@@ -1,574 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package s390x
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-	"cmd/oldlink/internal/sym"
-	"debug/elf"
-	"fmt"
-)
-
-// gentext generates assembly to append the local moduledata to the global
-// moduledata linked list at initialization time. This is only done if the runtime
-// is in a different module.
-//
-// <go.link.addmoduledata>:
-// 	larl  %r2, <local.moduledata>
-// 	jg    <runtime.addmoduledata@plt>
-//	undef
-//
-// The job of appending the moduledata is delegated to runtime.addmoduledata.
-func gentext(ctxt *ld.Link) {
-	if !ctxt.DynlinkingGo() {
-		return
-	}
-	addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-	if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
-		// we're linking a module containing the runtime -> no need for
-		// an init function
-		return
-	}
-	addmoduledata.Attr |= sym.AttrReachable
-	initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-	initfunc.Type = sym.STEXT
-	initfunc.Attr |= sym.AttrLocal
-	initfunc.Attr |= sym.AttrReachable
-
-	// larl %r2, <local.moduledata>
-	initfunc.AddUint8(0xc0)
-	initfunc.AddUint8(0x20)
-	lmd := initfunc.AddRel()
-	lmd.InitExt()
-	lmd.Off = int32(initfunc.Size)
-	lmd.Siz = 4
-	lmd.Sym = ctxt.Moduledata
-	lmd.Type = objabi.R_PCREL
-	lmd.Variant = sym.RV_390_DBL
-	lmd.Add = 2 + int64(lmd.Siz)
-	initfunc.AddUint32(ctxt.Arch, 0)
-
-	// jg <runtime.addmoduledata[@plt]>
-	initfunc.AddUint8(0xc0)
-	initfunc.AddUint8(0xf4)
-	rel := initfunc.AddRel()
-	rel.InitExt()
-	rel.Off = int32(initfunc.Size)
-	rel.Siz = 4
-	rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-	rel.Type = objabi.R_CALL
-	rel.Variant = sym.RV_390_DBL
-	rel.Add = 2 + int64(rel.Siz)
-	initfunc.AddUint32(ctxt.Arch, 0)
-
-	// undef (for debugging)
-	initfunc.AddUint32(ctxt.Arch, 0)
-	if ctxt.BuildMode == ld.BuildModePlugin {
-		ctxt.Textp = append(ctxt.Textp, addmoduledata)
-	}
-	ctxt.Textp = append(ctxt.Textp, initfunc)
-	initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-	initarray_entry.Attr |= sym.AttrLocal
-	initarray_entry.Attr |= sym.AttrReachable
-	initarray_entry.Type = sym.SINITARR
-	initarray_entry.AddAddr(ctxt.Arch, initfunc)
-}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-	targ := r.Sym
-	r.InitExt()
-
-	switch r.Type {
-	default:
-		if r.Type >= objabi.ElfRelocOffset {
-			ld.Errorf(s, "unexpected relocation type %d", r.Type)
-			return false
-		}
-
-		// Handle relocations found in ELF object files.
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_12),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOT12):
-		ld.Errorf(s, "s390x 12-bit relocations have not been implemented (relocation type %d)", r.Type-objabi.ElfRelocOffset)
-		return false
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_8),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_16),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_32),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_64):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected R_390_nn relocation for dynamic symbol %s", targ.Name)
-		}
-		r.Type = objabi.R_ADDR
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC16),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC32),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC64):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected R_390_PCnn relocation for dynamic symbol %s", targ.Name)
-		}
-		// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
-		// sense and should be removed when someone has thought about it properly.
-		if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
-			ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
-		}
-		r.Type = objabi.R_PCREL
-		r.Add += int64(r.Siz)
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOT16),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOT32),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOT64):
-		ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-objabi.ElfRelocOffset)
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PLT16DBL),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PLT32DBL):
-		r.Type = objabi.R_PCREL
-		r.Variant = sym.RV_390_DBL
-		r.Add += int64(r.Siz)
-		if targ.Type == sym.SDYNIMPORT {
-			addpltsym(ctxt, targ)
-			r.Sym = ctxt.Syms.Lookup(".plt", 0)
-			r.Add += int64(targ.Plt())
-		}
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PLT32),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PLT64):
-		r.Type = objabi.R_PCREL
-		r.Add += int64(r.Siz)
-		if targ.Type == sym.SDYNIMPORT {
-			addpltsym(ctxt, targ)
-			r.Sym = ctxt.Syms.Lookup(".plt", 0)
-			r.Add += int64(targ.Plt())
-		}
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_COPY):
-		ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-objabi.ElfRelocOffset)
-		return false
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GLOB_DAT):
-		ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-objabi.ElfRelocOffset)
-		return false
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_JMP_SLOT):
-		ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-objabi.ElfRelocOffset)
-		return false
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_RELATIVE):
-		ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-objabi.ElfRelocOffset)
-		return false
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTOFF):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected R_390_GOTOFF relocation for dynamic symbol %s", targ.Name)
-		}
-		r.Type = objabi.R_GOTOFF
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTPC):
-		r.Type = objabi.R_PCREL
-		r.Sym = ctxt.Syms.Lookup(".got", 0)
-		r.Add += int64(r.Siz)
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC16DBL),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC32DBL):
-		r.Type = objabi.R_PCREL
-		r.Variant = sym.RV_390_DBL
-		r.Add += int64(r.Siz)
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected R_390_PCnnDBL relocation for dynamic symbol %s", targ.Name)
-		}
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTPCDBL):
-		r.Type = objabi.R_PCREL
-		r.Variant = sym.RV_390_DBL
-		r.Sym = ctxt.Syms.Lookup(".got", 0)
-		r.Add += int64(r.Siz)
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTENT):
-		addgotsym(ctxt, targ)
-
-		r.Type = objabi.R_PCREL
-		r.Variant = sym.RV_390_DBL
-		r.Sym = ctxt.Syms.Lookup(".got", 0)
-		r.Add += int64(targ.Got())
-		r.Add += int64(r.Siz)
-		return true
-	}
-	// Handle references to ELF symbols from our own object files.
-	if targ.Type != sym.SDYNIMPORT {
-		return true
-	}
-
-	return false
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-	ctxt.Out.Write64(uint64(sectoff))
-
-	elfsym := r.Xsym.ElfsymForReloc()
-	switch r.Type {
-	default:
-		return false
-	case objabi.R_TLS_LE:
-		switch r.Siz {
-		default:
-			return false
-		case 4:
-			// WARNING - silently ignored by linker in ELF64
-			ctxt.Out.Write64(uint64(elf.R_390_TLS_LE32) | uint64(elfsym)<<32)
-		case 8:
-			// WARNING - silently ignored by linker in ELF32
-			ctxt.Out.Write64(uint64(elf.R_390_TLS_LE64) | uint64(elfsym)<<32)
-		}
-	case objabi.R_TLS_IE:
-		switch r.Siz {
-		default:
-			return false
-		case 4:
-			ctxt.Out.Write64(uint64(elf.R_390_TLS_IEENT) | uint64(elfsym)<<32)
-		}
-	case objabi.R_ADDR:
-		switch r.Siz {
-		default:
-			return false
-		case 4:
-			ctxt.Out.Write64(uint64(elf.R_390_32) | uint64(elfsym)<<32)
-		case 8:
-			ctxt.Out.Write64(uint64(elf.R_390_64) | uint64(elfsym)<<32)
-		}
-	case objabi.R_GOTPCREL:
-		if r.Siz == 4 {
-			ctxt.Out.Write64(uint64(elf.R_390_GOTENT) | uint64(elfsym)<<32)
-		} else {
-			return false
-		}
-	case objabi.R_PCREL, objabi.R_PCRELDBL, objabi.R_CALL:
-		elfrel := elf.R_390_NONE
-		isdbl := r.Variant&sym.RV_TYPE_MASK == sym.RV_390_DBL
-		// TODO(mundaym): all DBL style relocations should be
-		// signalled using the variant - see issue 14218.
-		switch r.Type {
-		case objabi.R_PCRELDBL, objabi.R_CALL:
-			isdbl = true
-		}
-		if r.Xsym.Type == sym.SDYNIMPORT && (r.Xsym.ElfType() == elf.STT_FUNC || r.Type == objabi.R_CALL) {
-			if isdbl {
-				switch r.Siz {
-				case 2:
-					elfrel = elf.R_390_PLT16DBL
-				case 4:
-					elfrel = elf.R_390_PLT32DBL
-				}
-			} else {
-				switch r.Siz {
-				case 4:
-					elfrel = elf.R_390_PLT32
-				case 8:
-					elfrel = elf.R_390_PLT64
-				}
-			}
-		} else {
-			if isdbl {
-				switch r.Siz {
-				case 2:
-					elfrel = elf.R_390_PC16DBL
-				case 4:
-					elfrel = elf.R_390_PC32DBL
-				}
-			} else {
-				switch r.Siz {
-				case 2:
-					elfrel = elf.R_390_PC16
-				case 4:
-					elfrel = elf.R_390_PC32
-				case 8:
-					elfrel = elf.R_390_PC64
-				}
-			}
-		}
-		if elfrel == elf.R_390_NONE {
-			return false // unsupported size/dbl combination
-		}
-		ctxt.Out.Write64(uint64(elfrel) | uint64(elfsym)<<32)
-	}
-
-	ctxt.Out.Write64(uint64(r.Xadd))
-	return true
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-	plt := ctxt.Syms.Lookup(".plt", 0)
-	got := ctxt.Syms.Lookup(".got", 0)
-	if plt.Size == 0 {
-		// stg     %r1,56(%r15)
-		plt.AddUint8(0xe3)
-		plt.AddUint8(0x10)
-		plt.AddUint8(0xf0)
-		plt.AddUint8(0x38)
-		plt.AddUint8(0x00)
-		plt.AddUint8(0x24)
-		// larl    %r1,_GLOBAL_OFFSET_TABLE_
-		plt.AddUint8(0xc0)
-		plt.AddUint8(0x10)
-		plt.AddPCRelPlus(ctxt.Arch, got, 6)
-		// mvc     48(8,%r15),8(%r1)
-		plt.AddUint8(0xd2)
-		plt.AddUint8(0x07)
-		plt.AddUint8(0xf0)
-		plt.AddUint8(0x30)
-		plt.AddUint8(0x10)
-		plt.AddUint8(0x08)
-		// lg      %r1,16(%r1)
-		plt.AddUint8(0xe3)
-		plt.AddUint8(0x10)
-		plt.AddUint8(0x10)
-		plt.AddUint8(0x10)
-		plt.AddUint8(0x00)
-		plt.AddUint8(0x04)
-		// br      %r1
-		plt.AddUint8(0x07)
-		plt.AddUint8(0xf1)
-		// nopr    %r0
-		plt.AddUint8(0x07)
-		plt.AddUint8(0x00)
-		// nopr    %r0
-		plt.AddUint8(0x07)
-		plt.AddUint8(0x00)
-		// nopr    %r0
-		plt.AddUint8(0x07)
-		plt.AddUint8(0x00)
-
-		// assume got->size == 0 too
-		got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
-
-		got.AddUint64(ctxt.Arch, 0)
-		got.AddUint64(ctxt.Arch, 0)
-	}
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-	return false
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-	if ctxt.LinkMode == ld.LinkExternal {
-		return val, false
-	}
-
-	switch r.Type {
-	case objabi.R_CONST:
-		return r.Add, true
-	case objabi.R_GOTOFF:
-		return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
-	}
-
-	return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-	switch r.Variant & sym.RV_TYPE_MASK {
-	default:
-		ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
-		return t
-
-	case sym.RV_NONE:
-		return t
-
-	case sym.RV_390_DBL:
-		if (t & 1) != 0 {
-			ld.Errorf(s, "%s+%v is not 2-byte aligned", r.Sym.Name, r.Sym.Value)
-		}
-		return t >> 1
-	}
-}
-
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
-	if s.Plt() >= 0 {
-		return
-	}
-
-	ld.Adddynsym(ctxt, s)
-
-	if ctxt.IsELF {
-		plt := ctxt.Syms.Lookup(".plt", 0)
-		got := ctxt.Syms.Lookup(".got", 0)
-		rela := ctxt.Syms.Lookup(".rela.plt", 0)
-		if plt.Size == 0 {
-			elfsetupplt(ctxt)
-		}
-		// larl    %r1,_GLOBAL_OFFSET_TABLE_+index
-
-		plt.AddUint8(0xc0)
-		plt.AddUint8(0x10)
-		plt.AddPCRelPlus(ctxt.Arch, got, got.Size+6) // need variant?
-
-		// add to got: pointer to current pos in plt
-		got.AddAddrPlus(ctxt.Arch, plt, plt.Size+8) // weird but correct
-		// lg      %r1,0(%r1)
-		plt.AddUint8(0xe3)
-		plt.AddUint8(0x10)
-		plt.AddUint8(0x10)
-		plt.AddUint8(0x00)
-		plt.AddUint8(0x00)
-		plt.AddUint8(0x04)
-		// br      %r1
-		plt.AddUint8(0x07)
-		plt.AddUint8(0xf1)
-		// basr    %r1,%r0
-		plt.AddUint8(0x0d)
-		plt.AddUint8(0x10)
-		// lgf     %r1,12(%r1)
-		plt.AddUint8(0xe3)
-		plt.AddUint8(0x10)
-		plt.AddUint8(0x10)
-		plt.AddUint8(0x0c)
-		plt.AddUint8(0x00)
-		plt.AddUint8(0x14)
-		// jg .plt
-		plt.AddUint8(0xc0)
-		plt.AddUint8(0xf4)
-
-		plt.AddUint32(ctxt.Arch, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation
-		//.plt index
-		plt.AddUint32(ctxt.Arch, uint32(rela.Size)) // rela size before current entry
-
-		// rela
-		rela.AddAddrPlus(ctxt.Arch, got, got.Size-8)
-
-		rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_JMP_SLOT)))
-		rela.AddUint64(ctxt.Arch, 0)
-
-		s.SetPlt(int32(plt.Size - 32))
-
-	} else {
-		ld.Errorf(s, "addpltsym: unsupported binary format")
-	}
-}
-
-func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
-	if s.Got() >= 0 {
-		return
-	}
-
-	ld.Adddynsym(ctxt, s)
-	got := ctxt.Syms.Lookup(".got", 0)
-	s.SetGot(int32(got.Size))
-	got.AddUint64(ctxt.Arch, 0)
-
-	if ctxt.IsELF {
-		rela := ctxt.Syms.Lookup(".rela", 0)
-		rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
-		rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_GLOB_DAT)))
-		rela.AddUint64(ctxt.Arch, 0)
-	} else {
-		ld.Errorf(s, "addgotsym: unsupported binary format")
-	}
-}
-
-func asmb(ctxt *ld.Link) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	sect := ld.Segtext.Sections[0]
-	ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-	ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-	for _, sect = range ld.Segtext.Sections[1:] {
-		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-		ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-	}
-	if ld.Segrelrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
-	}
-
-	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-	/* output symbol table */
-	ld.Symsize = 0
-
-	ld.Lcsize = 0
-	symo := uint32(0)
-	if !*ld.FlagS {
-		if !ctxt.IsELF {
-			ld.Errorf(nil, "unsupported executable format")
-		}
-		symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-		symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
-
-		ctxt.Out.SeekSet(int64(symo))
-		ld.Asmelfsym(ctxt)
-		ctxt.Out.Flush()
-		ctxt.Out.Write(ld.Elfstrdat)
-
-		if ctxt.LinkMode == ld.LinkExternal {
-			ld.Elfemitreloc(ctxt)
-		}
-	}
-
-	ctxt.Out.SeekSet(0)
-	switch ctxt.HeadType {
-	default:
-		ld.Errorf(nil, "unsupported operating system")
-	case objabi.Hlinux:
-		ld.Asmbelf(ctxt, int64(symo))
-	}
-
-	ctxt.Out.Flush()
-	if *ld.FlagC {
-		fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
-		fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
-		fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
-		fmt.Printf("symsize=%d\n", ld.Symsize)
-		fmt.Printf("lcsize=%d\n", ld.Lcsize)
-		fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
-	}
-}
diff --git a/src/cmd/oldlink/internal/s390x/l.go b/src/cmd/oldlink/internal/s390x/l.go
deleted file mode 100644
index 87d10ee..0000000
--- a/src/cmd/oldlink/internal/s390x/l.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package s390x
-
-// Writing object files.
-
-// cmd/9l/l.h from Vita Nuova.
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-const (
-	maxAlign  = 32 // max data alignment
-	minAlign  = 2  // min data alignment
-	funcAlign = 16
-)
-
-/* Used by ../internal/ld/dwarf.go */
-const (
-	dwarfRegSP = 15
-	dwarfRegLR = 14
-)
diff --git a/src/cmd/oldlink/internal/s390x/obj.go b/src/cmd/oldlink/internal/s390x/obj.go
deleted file mode 100644
index b4af86b..0000000
--- a/src/cmd/oldlink/internal/s390x/obj.go
+++ /dev/null
@@ -1,88 +0,0 @@
-// Inferno utils/5l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/obj.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package s390x
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-	arch := sys.ArchS390X
-
-	theArch := ld.Arch{
-		Funcalign:  funcAlign,
-		Maxalign:   maxAlign,
-		Minalign:   minAlign,
-		Dwarfregsp: dwarfRegSP,
-		Dwarfreglr: dwarfRegLR,
-
-		Adddynrel:        adddynrel,
-		Archinit:         archinit,
-		Archreloc:        archreloc,
-		Archrelocvariant: archrelocvariant,
-		Asmb:             asmb,  // in asm.go
-		Asmb2:            asmb2, // in asm.go
-		Elfreloc1:        elfreloc1,
-		Elfsetupplt:      elfsetupplt,
-		Gentext:          gentext,
-		Machoreloc1:      machoreloc1,
-
-		Linuxdynld: "/lib64/ld64.so.1",
-
-		// not relevant for s390x
-		Freebsddynld:   "XXX",
-		Openbsddynld:   "XXX",
-		Netbsddynld:    "XXX",
-		Dragonflydynld: "XXX",
-		Solarisdynld:   "XXX",
-	}
-
-	return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-	switch ctxt.HeadType {
-	default:
-		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-
-	case objabi.Hlinux: // s390x ELF
-		ld.Elfinit(ctxt)
-		ld.HEADR = ld.ELFRESERVE
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 0x10000
-		}
-	}
-}
diff --git a/src/cmd/oldlink/internal/sym/attribute.go b/src/cmd/oldlink/internal/sym/attribute.go
deleted file mode 100644
index 4b69bf3..0000000
--- a/src/cmd/oldlink/internal/sym/attribute.go
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sym
-
-// Attribute is a set of common symbol attributes.
-type Attribute int32
-
-const (
-	// AttrDuplicateOK marks a symbol that can be present in multiple object
-	// files.
-	AttrDuplicateOK Attribute = 1 << iota
-	// AttrExternal marks function symbols loaded from host object files.
-	AttrExternal
-	// AttrNoSplit marks functions that cannot split the stack; the linker
-	// cares because it checks that there are no call chains of nosplit
-	// functions that require more than StackLimit bytes (see
-	// lib.go:dostkcheck)
-	AttrNoSplit
-	// AttrReachable marks symbols that are transitively referenced from the
-	// entry points. Unreachable symbols are not written to the output.
-	AttrReachable
-	// AttrCgoExportDynamic and AttrCgoExportStatic mark symbols referenced
-	// by directives written by cgo (in response to //export directives in
-	// the source).
-	AttrCgoExportDynamic
-	AttrCgoExportStatic
-	// AttrSpecial marks symbols that do not have their address (i.e. Value)
-	// computed by the usual mechanism of data.go:dodata() &
-	// data.go:address().
-	AttrSpecial
-	// AttrStackCheck is used by dostkcheck to only check each NoSplit
-	// function's stack usage once.
-	AttrStackCheck
-	// AttrNotInSymbolTable marks symbols that are not written to the symbol table.
-	AttrNotInSymbolTable
-	// AttrOnList marks symbols that are on some list (such as the list of
-	// all text symbols, or one of the lists of data symbols) and is
-	// consulted to avoid bugs where a symbol is put on a list twice.
-	AttrOnList
-	// AttrLocal marks symbols that are only visible within the module
-	// (executable or shared library) being linked. Only relevant when
-	// dynamically linking Go code.
-	AttrLocal
-	// AttrReflectMethod marks certain methods from the reflect package that
-	// can be used to call arbitrary methods. If no symbol with this bit set
-	// is marked as reachable, more dead code elimination can be done.
-	AttrReflectMethod
-	// AttrMakeTypelink Amarks types that should be added to the typelink
-	// table. See typelinks.go:typelinks().
-	AttrMakeTypelink
-	// AttrShared marks symbols compiled with the -shared option.
-	AttrShared
-	// AttrVisibilityHidden symbols are ELF symbols with
-	// visibility set to STV_HIDDEN. They become local symbols in
-	// the final executable. Only relevant when internally linking
-	// on an ELF platform.
-	AttrVisibilityHidden
-	// AttrSubSymbol mostly means that the symbol appears on the Sub list of some
-	// other symbol.  Unfortunately, it's not 100% reliable; at least, it's not set
-	// correctly for the .TOC. symbol in Link.dodata.  Usually the Outer field of the
-	// symbol points to the symbol whose list it is on, but that it is not set for the
-	// symbols added to .windynamic in initdynimport in pe.go.
-	//
-	// TODO(mwhudson): fix the inconsistencies noticed above.
-	//
-	// Sub lists are used when loading host objects (sections from the host object
-	// become regular linker symbols and symbols go on the Sub list of their section)
-	// and for constructing the global offset table when internally linking a dynamic
-	// executable.
-	//
-	// TODO(mwhudson): perhaps a better name for this is AttrNonGoSymbol.
-	AttrSubSymbol
-	// AttrContainer is set on text symbols that are present as the .Outer for some
-	// other symbol.
-	AttrContainer
-	// AttrTopFrame means that the function is an entry point and unwinders
-	// should stop when they hit this function.
-	AttrTopFrame
-	// AttrReadOnly indicates whether the symbol's content (Symbol.P) is backed by
-	// read-only memory.
-	AttrReadOnly
-	// 19 attributes defined so far.
-)
-
-func (a Attribute) DuplicateOK() bool      { return a&AttrDuplicateOK != 0 }
-func (a Attribute) External() bool         { return a&AttrExternal != 0 }
-func (a Attribute) NoSplit() bool          { return a&AttrNoSplit != 0 }
-func (a Attribute) Reachable() bool        { return a&AttrReachable != 0 }
-func (a Attribute) CgoExportDynamic() bool { return a&AttrCgoExportDynamic != 0 }
-func (a Attribute) CgoExportStatic() bool  { return a&AttrCgoExportStatic != 0 }
-func (a Attribute) Special() bool          { return a&AttrSpecial != 0 }
-func (a Attribute) StackCheck() bool       { return a&AttrStackCheck != 0 }
-func (a Attribute) NotInSymbolTable() bool { return a&AttrNotInSymbolTable != 0 }
-func (a Attribute) OnList() bool           { return a&AttrOnList != 0 }
-func (a Attribute) Local() bool            { return a&AttrLocal != 0 }
-func (a Attribute) ReflectMethod() bool    { return a&AttrReflectMethod != 0 }
-func (a Attribute) MakeTypelink() bool     { return a&AttrMakeTypelink != 0 }
-func (a Attribute) Shared() bool           { return a&AttrShared != 0 }
-func (a Attribute) VisibilityHidden() bool { return a&AttrVisibilityHidden != 0 }
-func (a Attribute) SubSymbol() bool        { return a&AttrSubSymbol != 0 }
-func (a Attribute) Container() bool        { return a&AttrContainer != 0 }
-func (a Attribute) TopFrame() bool         { return a&AttrTopFrame != 0 }
-func (a Attribute) ReadOnly() bool         { return a&AttrReadOnly != 0 }
-
-func (a Attribute) CgoExport() bool {
-	return a.CgoExportDynamic() || a.CgoExportStatic()
-}
-
-func (a *Attribute) Set(flag Attribute, value bool) {
-	if value {
-		*a |= flag
-	} else {
-		*a &^= flag
-	}
-}
diff --git a/src/cmd/oldlink/internal/sym/compilation_unit.go b/src/cmd/oldlink/internal/sym/compilation_unit.go
deleted file mode 100644
index 02fb0cf..0000000
--- a/src/cmd/oldlink/internal/sym/compilation_unit.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2019 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 sym
-
-import "cmd/internal/dwarf"
-
-// CompilationUnit is an abstraction used by DWARF to represent a chunk of
-// debug-related data. We create a CompilationUnit per Object file in a
-// library (so, one for all the Go code, one for each assembly file, etc.).
-type CompilationUnit struct {
-	Pkg            string        // The package name, eg ("fmt", or "runtime")
-	Lib            *Library      // Our library
-	Consts         *Symbol       // Package constants DIEs
-	PCs            []dwarf.Range // PC ranges, relative to Textp[0]
-	DWInfo         *dwarf.DWDie  // CU root DIE
-	FuncDIEs       []*Symbol     // Function DIE subtrees
-	AbsFnDIEs      []*Symbol     // Abstract function DIE subtrees
-	RangeSyms      []*Symbol     // Symbols for debug_range
-	Textp          []*Symbol     // Text symbols in this CU
-	DWARFFileTable []string      // The file table used to generate the .debug_lines
-}
diff --git a/src/cmd/oldlink/internal/sym/library.go b/src/cmd/oldlink/internal/sym/library.go
deleted file mode 100644
index 4f2023b..0000000
--- a/src/cmd/oldlink/internal/sym/library.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sym
-
-type Library struct {
-	Objref        string
-	Srcref        string
-	File          string
-	Pkg           string
-	Shlib         string
-	Hash          string
-	ImportStrings []string
-	Imports       []*Library
-	Textp         []*Symbol // text symbols defined in this library
-	DupTextSyms   []*Symbol // dupok text symbols defined in this library
-	Main          bool
-	Safe          bool
-	Units         []*CompilationUnit
-}
-
-func (l Library) String() string {
-	return l.Pkg
-}
diff --git a/src/cmd/oldlink/internal/sym/reloc.go b/src/cmd/oldlink/internal/sym/reloc.go
deleted file mode 100644
index 4809db8..0000000
--- a/src/cmd/oldlink/internal/sym/reloc.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sym
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"debug/elf"
-)
-
-// Reloc is a relocation.
-//
-// The typical Reloc rewrites part of a symbol at offset Off to address Sym.
-// A Reloc is stored in a slice on the Symbol it rewrites.
-//
-// Relocations are generated by the compiler as the type
-// cmd/internal/obj.Reloc, which is encoded into the object file wire
-// format and decoded by the linker into this type. A separate type is
-// used to hold linker-specific state about the relocation.
-//
-// Some relocations are created by cmd/link.
-type Reloc struct {
-	Off       int32            // offset to rewrite
-	Siz       uint8            // number of bytes to rewrite, 1, 2, or 4
-	Done      bool             // set to true when relocation is complete
-	Type      objabi.RelocType // the relocation type
-	Add       int64            // addend
-	Sym       *Symbol          // symbol the relocation addresses
-	*relocExt                  // extra fields (see below), may be nil, call InitExt before use
-}
-
-// relocExt contains extra fields in Reloc that are used only in
-// certain cases.
-type relocExt struct {
-	Xadd    int64        // addend passed to external linker
-	Xsym    *Symbol      // symbol passed to external linker
-	Variant RelocVariant // variation on Type, currently used only on PPC64 and S390X
-}
-
-func (r *Reloc) InitExt() {
-	if r.relocExt == nil {
-		r.relocExt = new(relocExt)
-	}
-}
-
-// RelocVariant is a linker-internal variation on a relocation.
-type RelocVariant uint8
-
-const (
-	RV_NONE RelocVariant = iota
-	RV_POWER_LO
-	RV_POWER_HI
-	RV_POWER_HA
-	RV_POWER_DS
-
-	// RV_390_DBL is a s390x-specific relocation variant that indicates that
-	// the value to be placed into the relocatable field should first be
-	// divided by 2.
-	RV_390_DBL
-
-	RV_CHECK_OVERFLOW RelocVariant = 1 << 7
-	RV_TYPE_MASK      RelocVariant = RV_CHECK_OVERFLOW - 1
-)
-
-func RelocName(arch *sys.Arch, r objabi.RelocType) string {
-	// We didn't have some relocation types at Go1.4.
-	// Uncomment code when we include those in bootstrap code.
-
-	switch {
-	case r >= objabi.MachoRelocOffset: // Mach-O
-		// nr := (r - objabi.MachoRelocOffset)>>1
-		// switch ctxt.Arch.Family {
-		// case sys.AMD64:
-		// 	return macho.RelocTypeX86_64(nr).String()
-		// case sys.ARM:
-		// 	return macho.RelocTypeARM(nr).String()
-		// case sys.ARM64:
-		// 	return macho.RelocTypeARM64(nr).String()
-		// case sys.I386:
-		// 	return macho.RelocTypeGeneric(nr).String()
-		// default:
-		// 	panic("unreachable")
-		// }
-	case r >= objabi.ElfRelocOffset: // ELF
-		nr := r - objabi.ElfRelocOffset
-		switch arch.Family {
-		case sys.AMD64:
-			return elf.R_X86_64(nr).String()
-		case sys.ARM:
-			return elf.R_ARM(nr).String()
-		case sys.ARM64:
-			return elf.R_AARCH64(nr).String()
-		case sys.I386:
-			return elf.R_386(nr).String()
-		case sys.MIPS, sys.MIPS64:
-			return elf.R_MIPS(nr).String()
-		case sys.PPC64:
-			return elf.R_PPC64(nr).String()
-		case sys.S390X:
-			return elf.R_390(nr).String()
-		default:
-			panic("unreachable")
-		}
-	}
-
-	return r.String()
-}
-
-// RelocByOff implements sort.Interface for sorting relocations by offset.
-type RelocByOff []Reloc
-
-func (x RelocByOff) Len() int { return len(x) }
-
-func (x RelocByOff) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-
-func (x RelocByOff) Less(i, j int) bool {
-	a := &x[i]
-	b := &x[j]
-	if a.Off < b.Off {
-		return true
-	}
-	if a.Off > b.Off {
-		return false
-	}
-	return false
-}
diff --git a/src/cmd/oldlink/internal/sym/segment.go b/src/cmd/oldlink/internal/sym/segment.go
deleted file mode 100644
index d5255bf..0000000
--- a/src/cmd/oldlink/internal/sym/segment.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Inferno utils/8l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/8l/asm.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package sym
-
-// Terrible but standard terminology.
-// A segment describes a block of file to load into memory.
-// A section further describes the pieces of that block for
-// use in debuggers and such.
-
-type Segment struct {
-	Rwx      uint8  // permission as usual unix bits (5 = r-x etc)
-	Vaddr    uint64 // virtual address
-	Length   uint64 // length in memory
-	Fileoff  uint64 // file offset
-	Filelen  uint64 // length on disk
-	Sections []*Section
-}
-
-type Section struct {
-	Rwx     uint8
-	Extnum  int16
-	Align   int32
-	Name    string
-	Vaddr   uint64
-	Length  uint64
-	Seg     *Segment
-	Elfsect interface{} // an *ld.ElfShdr
-	Reloff  uint64
-	Rellen  uint64
-}
diff --git a/src/cmd/oldlink/internal/sym/sizeof_test.go b/src/cmd/oldlink/internal/sym/sizeof_test.go
deleted file mode 100644
index e6e3916..0000000
--- a/src/cmd/oldlink/internal/sym/sizeof_test.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2018 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 sym
-
-import (
-	"reflect"
-	"testing"
-	"unsafe"
-)
-
-// Assert that the size of important structures do not change unexpectedly.
-
-func TestSizeof(t *testing.T) {
-	const nbit = unsafe.Sizeof(uintptr(0)) * 8
-	const _64bit = nbit == 64
-
-	var tests = []struct {
-		val    interface{} // type as a value
-		_32bit uintptr     // size on 32bit platforms
-		_64bit uintptr     // size on 64bit platforms
-	}{
-		{Symbol{}, 108, 176},
-	}
-
-	for _, tt := range tests {
-		want := tt._32bit
-		if _64bit {
-			want = tt._64bit
-		}
-		got := reflect.TypeOf(tt.val).Size()
-		if want != got {
-			t.Errorf("%d bit unsafe.Sizeof(%T) = %d, want %d", nbit, tt.val, got, want)
-		}
-	}
-}
diff --git a/src/cmd/oldlink/internal/sym/symbol.go b/src/cmd/oldlink/internal/sym/symbol.go
deleted file mode 100644
index 2756acd..0000000
--- a/src/cmd/oldlink/internal/sym/symbol.go
+++ /dev/null
@@ -1,543 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sym
-
-import (
-	"cmd/internal/obj"
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"debug/elf"
-	"fmt"
-	"log"
-)
-
-// Symbol is an entry in the symbol table.
-type Symbol struct {
-	Name        string
-	Type        SymKind
-	Version     int16
-	Attr        Attribute
-	Dynid       int32
-	Align       int32
-	Elfsym      int32
-	LocalElfsym int32
-	Value       int64
-	Size        int64
-	Sub         *Symbol
-	Outer       *Symbol
-	Gotype      *Symbol
-	File        string // actually package!
-	auxinfo     *AuxSymbol
-	Sect        *Section
-	FuncInfo    *FuncInfo
-	Unit        *CompilationUnit
-	// P contains the raw symbol data.
-	P []byte
-	R []Reloc
-}
-
-// AuxSymbol contains less-frequently used sym.Symbol fields.
-type AuxSymbol struct {
-	extname    string
-	dynimplib  string
-	dynimpvers string
-	localentry uint8
-	plt        int32
-	got        int32
-	// ElfType is set for symbols read from shared libraries by ldshlibsyms. It
-	// is not set for symbols defined by the packages being linked or by symbols
-	// read by ldelf (and so is left as elf.STT_NOTYPE).
-	elftype elf.SymType
-}
-
-const (
-	SymVerABI0        = 0
-	SymVerABIInternal = 1
-	SymVerStatic      = 10 // Minimum version used by static (file-local) syms
-)
-
-func ABIToVersion(abi obj.ABI) int {
-	switch abi {
-	case obj.ABI0:
-		return SymVerABI0
-	case obj.ABIInternal:
-		return SymVerABIInternal
-	}
-	return -1
-}
-
-func VersionToABI(v int) (obj.ABI, bool) {
-	switch v {
-	case SymVerABI0:
-		return obj.ABI0, true
-	case SymVerABIInternal:
-		return obj.ABIInternal, true
-	}
-	return ^obj.ABI(0), false
-}
-
-func (s *Symbol) String() string {
-	if s.Version == 0 {
-		return s.Name
-	}
-	return fmt.Sprintf("%s<%d>", s.Name, s.Version)
-}
-
-func (s *Symbol) IsFileLocal() bool {
-	return s.Version >= SymVerStatic
-}
-
-func (s *Symbol) ElfsymForReloc() int32 {
-	// If putelfsym created a local version of this symbol, use that in all
-	// relocations.
-	if s.LocalElfsym != 0 {
-		return s.LocalElfsym
-	} else {
-		return s.Elfsym
-	}
-}
-
-func (s *Symbol) Length(_ interface{}) int64 {
-	return s.Size
-}
-
-func (s *Symbol) Grow(siz int64) {
-	if int64(int(siz)) != siz {
-		log.Fatalf("symgrow size %d too long", siz)
-	}
-	if int64(len(s.P)) >= siz {
-		return
-	}
-	if cap(s.P) < int(siz) {
-		p := make([]byte, 2*(siz+1))
-		s.P = append(p[:0], s.P...)
-	}
-	s.P = s.P[:siz]
-}
-
-func (s *Symbol) AddBytes(bytes []byte) int64 {
-	if s.Type == 0 {
-		s.Type = SDATA
-	}
-	s.Attr |= AttrReachable
-	s.P = append(s.P, bytes...)
-	s.Size = int64(len(s.P))
-
-	return s.Size
-}
-
-func (s *Symbol) AddUint8(v uint8) int64 {
-	off := s.Size
-	if s.Type == 0 {
-		s.Type = SDATA
-	}
-	s.Attr |= AttrReachable
-	s.Size++
-	s.P = append(s.P, v)
-
-	return off
-}
-
-func (s *Symbol) AddUint16(arch *sys.Arch, v uint16) int64 {
-	return s.AddUintXX(arch, uint64(v), 2)
-}
-
-func (s *Symbol) AddUint32(arch *sys.Arch, v uint32) int64 {
-	return s.AddUintXX(arch, uint64(v), 4)
-}
-
-func (s *Symbol) AddUint64(arch *sys.Arch, v uint64) int64 {
-	return s.AddUintXX(arch, v, 8)
-}
-
-func (s *Symbol) AddUint(arch *sys.Arch, v uint64) int64 {
-	return s.AddUintXX(arch, v, arch.PtrSize)
-}
-
-func (s *Symbol) SetUint8(arch *sys.Arch, r int64, v uint8) int64 {
-	return s.setUintXX(arch, r, uint64(v), 1)
-}
-
-func (s *Symbol) SetUint16(arch *sys.Arch, r int64, v uint16) int64 {
-	return s.setUintXX(arch, r, uint64(v), 2)
-}
-
-func (s *Symbol) SetUint32(arch *sys.Arch, r int64, v uint32) int64 {
-	return s.setUintXX(arch, r, uint64(v), 4)
-}
-
-func (s *Symbol) SetUint(arch *sys.Arch, r int64, v uint64) int64 {
-	return s.setUintXX(arch, r, v, int64(arch.PtrSize))
-}
-
-func (s *Symbol) addAddrPlus(arch *sys.Arch, t *Symbol, add int64, typ objabi.RelocType) int64 {
-	if s.Type == 0 {
-		s.Type = SDATA
-	}
-	s.Attr |= AttrReachable
-	i := s.Size
-	s.Size += int64(arch.PtrSize)
-	s.Grow(s.Size)
-	r := s.AddRel()
-	r.Sym = t
-	r.Off = int32(i)
-	r.Siz = uint8(arch.PtrSize)
-	r.Type = typ
-	r.Add = add
-	return i + int64(r.Siz)
-}
-
-func (s *Symbol) AddAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
-	return s.addAddrPlus(arch, t, add, objabi.R_ADDR)
-}
-
-func (s *Symbol) AddCURelativeAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
-	return s.addAddrPlus(arch, t, add, objabi.R_ADDRCUOFF)
-}
-
-func (s *Symbol) AddPCRelPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
-	if s.Type == 0 {
-		s.Type = SDATA
-	}
-	s.Attr |= AttrReachable
-	i := s.Size
-	s.Size += 4
-	s.Grow(s.Size)
-	r := s.AddRel()
-	r.Sym = t
-	r.Off = int32(i)
-	r.Add = add
-	r.Type = objabi.R_PCREL
-	r.Siz = 4
-	if arch.Family == sys.S390X || arch.Family == sys.PPC64 {
-		r.InitExt()
-	}
-	if arch.Family == sys.S390X {
-		r.Variant = RV_390_DBL
-	}
-	return i + int64(r.Siz)
-}
-
-func (s *Symbol) AddAddr(arch *sys.Arch, t *Symbol) int64 {
-	return s.AddAddrPlus(arch, t, 0)
-}
-
-func (s *Symbol) SetAddrPlus(arch *sys.Arch, off int64, t *Symbol, add int64) int64 {
-	if s.Type == 0 {
-		s.Type = SDATA
-	}
-	s.Attr |= AttrReachable
-	if off+int64(arch.PtrSize) > s.Size {
-		s.Size = off + int64(arch.PtrSize)
-		s.Grow(s.Size)
-	}
-
-	r := s.AddRel()
-	r.Sym = t
-	r.Off = int32(off)
-	r.Siz = uint8(arch.PtrSize)
-	r.Type = objabi.R_ADDR
-	r.Add = add
-	return off + int64(r.Siz)
-}
-
-func (s *Symbol) SetAddr(arch *sys.Arch, off int64, t *Symbol) int64 {
-	return s.SetAddrPlus(arch, off, t, 0)
-}
-
-func (s *Symbol) AddSize(arch *sys.Arch, t *Symbol) int64 {
-	if s.Type == 0 {
-		s.Type = SDATA
-	}
-	s.Attr |= AttrReachable
-	i := s.Size
-	s.Size += int64(arch.PtrSize)
-	s.Grow(s.Size)
-	r := s.AddRel()
-	r.Sym = t
-	r.Off = int32(i)
-	r.Siz = uint8(arch.PtrSize)
-	r.Type = objabi.R_SIZE
-	return i + int64(r.Siz)
-}
-
-func (s *Symbol) AddAddrPlus4(t *Symbol, add int64) int64 {
-	if s.Type == 0 {
-		s.Type = SDATA
-	}
-	s.Attr |= AttrReachable
-	i := s.Size
-	s.Size += 4
-	s.Grow(s.Size)
-	r := s.AddRel()
-	r.Sym = t
-	r.Off = int32(i)
-	r.Siz = 4
-	r.Type = objabi.R_ADDR
-	r.Add = add
-	return i + int64(r.Siz)
-}
-
-func (s *Symbol) AddRel() *Reloc {
-	s.R = append(s.R, Reloc{})
-	return &s.R[len(s.R)-1]
-}
-
-func (s *Symbol) AddUintXX(arch *sys.Arch, v uint64, wid int) int64 {
-	off := s.Size
-	s.setUintXX(arch, off, v, int64(wid))
-	return off
-}
-
-func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64 {
-	if s.Type == 0 {
-		s.Type = SDATA
-	}
-	s.Attr |= AttrReachable
-	if s.Size < off+wid {
-		s.Size = off + wid
-		s.Grow(s.Size)
-	}
-
-	switch wid {
-	case 1:
-		s.P[off] = uint8(v)
-	case 2:
-		arch.ByteOrder.PutUint16(s.P[off:], uint16(v))
-	case 4:
-		arch.ByteOrder.PutUint32(s.P[off:], uint32(v))
-	case 8:
-		arch.ByteOrder.PutUint64(s.P[off:], v)
-	}
-
-	return off + wid
-}
-
-func (s *Symbol) makeAuxInfo() {
-	if s.auxinfo == nil {
-		s.auxinfo = &AuxSymbol{extname: s.Name, plt: -1, got: -1}
-	}
-}
-
-func (s *Symbol) Extname() string {
-	if s.auxinfo == nil {
-		return s.Name
-	}
-	return s.auxinfo.extname
-}
-
-func (s *Symbol) SetExtname(n string) {
-	if s.auxinfo == nil {
-		if s.Name == n {
-			return
-		}
-		s.makeAuxInfo()
-	}
-	s.auxinfo.extname = n
-}
-
-func (s *Symbol) Dynimplib() string {
-	if s.auxinfo == nil {
-		return ""
-	}
-	return s.auxinfo.dynimplib
-}
-
-func (s *Symbol) Dynimpvers() string {
-	if s.auxinfo == nil {
-		return ""
-	}
-	return s.auxinfo.dynimpvers
-}
-
-func (s *Symbol) SetDynimplib(lib string) {
-	if s.auxinfo == nil {
-		s.makeAuxInfo()
-	}
-	s.auxinfo.dynimplib = lib
-}
-
-func (s *Symbol) SetDynimpvers(vers string) {
-	if s.auxinfo == nil {
-		s.makeAuxInfo()
-	}
-	s.auxinfo.dynimpvers = vers
-}
-
-func (s *Symbol) ResetDyninfo() {
-	if s.auxinfo != nil {
-		s.auxinfo.dynimplib = ""
-		s.auxinfo.dynimpvers = ""
-	}
-}
-
-func (s *Symbol) Localentry() uint8 {
-	if s.auxinfo == nil {
-		return 0
-	}
-	return s.auxinfo.localentry
-}
-
-func (s *Symbol) SetLocalentry(val uint8) {
-	if s.auxinfo == nil {
-		if val != 0 {
-			return
-		}
-		s.makeAuxInfo()
-	}
-	s.auxinfo.localentry = val
-}
-
-func (s *Symbol) Plt() int32 {
-	if s.auxinfo == nil {
-		return -1
-	}
-	return s.auxinfo.plt
-}
-
-func (s *Symbol) SetPlt(val int32) {
-	if s.auxinfo == nil {
-		if val == -1 {
-			return
-		}
-		s.makeAuxInfo()
-	}
-	s.auxinfo.plt = val
-}
-
-func (s *Symbol) Got() int32 {
-	if s.auxinfo == nil {
-		return -1
-	}
-	return s.auxinfo.got
-}
-
-func (s *Symbol) SetGot(val int32) {
-	if s.auxinfo == nil {
-		if val == -1 {
-			return
-		}
-		s.makeAuxInfo()
-	}
-	s.auxinfo.got = val
-}
-
-func (s *Symbol) ElfType() elf.SymType {
-	if s.auxinfo == nil {
-		return elf.STT_NOTYPE
-	}
-	return s.auxinfo.elftype
-}
-
-func (s *Symbol) SetElfType(val elf.SymType) {
-	if s.auxinfo == nil {
-		if val == elf.STT_NOTYPE {
-			return
-		}
-		s.makeAuxInfo()
-	}
-	s.auxinfo.elftype = val
-}
-
-// SortSub sorts a linked-list (by Sub) of *Symbol by Value.
-// Used for sub-symbols when loading host objects (see e.g. ldelf.go).
-func SortSub(l *Symbol) *Symbol {
-	if l == nil || l.Sub == nil {
-		return l
-	}
-
-	l1 := l
-	l2 := l
-	for {
-		l2 = l2.Sub
-		if l2 == nil {
-			break
-		}
-		l2 = l2.Sub
-		if l2 == nil {
-			break
-		}
-		l1 = l1.Sub
-	}
-
-	l2 = l1.Sub
-	l1.Sub = nil
-	l1 = SortSub(l)
-	l2 = SortSub(l2)
-
-	/* set up lead element */
-	if l1.Value < l2.Value {
-		l = l1
-		l1 = l1.Sub
-	} else {
-		l = l2
-		l2 = l2.Sub
-	}
-
-	le := l
-
-	for {
-		if l1 == nil {
-			for l2 != nil {
-				le.Sub = l2
-				le = l2
-				l2 = l2.Sub
-			}
-
-			le.Sub = nil
-			break
-		}
-
-		if l2 == nil {
-			for l1 != nil {
-				le.Sub = l1
-				le = l1
-				l1 = l1.Sub
-			}
-
-			break
-		}
-
-		if l1.Value < l2.Value {
-			le.Sub = l1
-			le = l1
-			l1 = l1.Sub
-		} else {
-			le.Sub = l2
-			le = l2
-			l2 = l2.Sub
-		}
-	}
-
-	le.Sub = nil
-	return l
-}
-
-type FuncInfo struct {
-	Args        int32
-	Locals      int32
-	Pcsp        Pcdata
-	Pcfile      Pcdata
-	Pcline      Pcdata
-	Pcinline    Pcdata
-	Pcdata      []Pcdata
-	Funcdata    []*Symbol
-	Funcdataoff []int64
-	File        []*Symbol
-	InlTree     []InlinedCall
-}
-
-// InlinedCall is a node in a local inlining tree (FuncInfo.InlTree).
-type InlinedCall struct {
-	Parent   int32   // index of parent in InlTree
-	File     *Symbol // file of the inlined call
-	Line     int32   // line number of the inlined call
-	Func     string  // name of the function that was inlined
-	ParentPC int32   // PC of the instruction just before the inlined body (offset from function start)
-}
-
-type Pcdata struct {
-	P []byte
-}
diff --git a/src/cmd/oldlink/internal/sym/symbols.go b/src/cmd/oldlink/internal/sym/symbols.go
deleted file mode 100644
index e772496..0000000
--- a/src/cmd/oldlink/internal/sym/symbols.go
+++ /dev/null
@@ -1,135 +0,0 @@
-// Derived from Inferno utils/6l/l.h and related files.
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package sym
-
-type Symbols struct {
-	symbolBatch []Symbol
-
-	// Symbol lookup based on name and indexed by version.
-	hash []map[string]*Symbol
-
-	Allsym []*Symbol
-}
-
-func NewSymbols() *Symbols {
-	hash := make([]map[string]*Symbol, SymVerStatic)
-	// Preallocate about 2mb for hash of non static symbols
-	hash[0] = make(map[string]*Symbol, 100000)
-	// And another 1mb for internal ABI text symbols.
-	hash[SymVerABIInternal] = make(map[string]*Symbol, 50000)
-	return &Symbols{
-		hash:   hash,
-		Allsym: make([]*Symbol, 0, 100000),
-	}
-}
-
-func (syms *Symbols) Newsym(name string, v int) *Symbol {
-	batch := syms.symbolBatch
-	if len(batch) == 0 {
-		batch = make([]Symbol, 1000)
-	}
-	s := &batch[0]
-	syms.symbolBatch = batch[1:]
-
-	s.Dynid = -1
-	s.Name = name
-	s.Version = int16(v)
-	syms.Allsym = append(syms.Allsym, s)
-
-	return s
-}
-
-// Look up the symbol with the given name and version, creating the
-// symbol if it is not found.
-func (syms *Symbols) Lookup(name string, v int) *Symbol {
-	m := syms.hash[v]
-	s := m[name]
-	if s != nil {
-		return s
-	}
-	s = syms.Newsym(name, v)
-	m[name] = s
-	return s
-}
-
-// Look up the symbol with the given name and version, returning nil
-// if it is not found.
-func (syms *Symbols) ROLookup(name string, v int) *Symbol {
-	return syms.hash[v][name]
-}
-
-// Add an existing symbol to the symbol table.
-func (syms *Symbols) Add(s *Symbol) {
-	name := s.Name
-	v := int(s.Version)
-	m := syms.hash[v]
-	if _, ok := m[name]; ok {
-		panic(name + " already added")
-	}
-	m[name] = s
-}
-
-// Allocate a new version (i.e. symbol namespace).
-func (syms *Symbols) IncVersion() int {
-	syms.hash = append(syms.hash, make(map[string]*Symbol))
-	return len(syms.hash) - 1
-}
-
-// Rename renames a symbol.
-func (syms *Symbols) Rename(old, new string, v int, reachparent map[*Symbol]*Symbol) {
-	s := syms.hash[v][old]
-	oldExtName := s.Extname()
-	s.Name = new
-	if oldExtName == old {
-		s.SetExtname(new)
-	}
-	delete(syms.hash[v], old)
-
-	dup := syms.hash[v][new]
-	if dup == nil {
-		syms.hash[v][new] = s
-	} else {
-		if s.Type == 0 {
-			dup.Attr |= s.Attr
-			if s.Attr.Reachable() && reachparent != nil {
-				reachparent[dup] = reachparent[s]
-			}
-			*s = *dup
-		} else if dup.Type == 0 {
-			s.Attr |= dup.Attr
-			if dup.Attr.Reachable() && reachparent != nil {
-				reachparent[s] = reachparent[dup]
-			}
-			*dup = *s
-			syms.hash[v][new] = s
-		}
-	}
-}
diff --git a/src/cmd/oldlink/internal/sym/symkind.go b/src/cmd/oldlink/internal/sym/symkind.go
deleted file mode 100644
index 1933dd7..0000000
--- a/src/cmd/oldlink/internal/sym/symkind.go
+++ /dev/null
@@ -1,168 +0,0 @@
-// Derived from Inferno utils/6l/l.h and related files.
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package sym
-
-// A SymKind describes the kind of memory represented by a symbol.
-type SymKind uint8
-
-// Defined SymKind values.
-//
-// TODO(rsc): Give idiomatic Go names.
-//go:generate stringer -type=SymKind
-const (
-	Sxxx SymKind = iota
-	STEXT
-	SELFRXSECT
-
-	// Read-only sections.
-	STYPE
-	SSTRING
-	SGOSTRING
-	SGOFUNC
-	SGCBITS
-	SRODATA
-	SFUNCTAB
-
-	SELFROSECT
-	SMACHOPLT
-
-	// Read-only sections with relocations.
-	//
-	// Types STYPE-SFUNCTAB above are written to the .rodata section by default.
-	// When linking a shared object, some conceptually "read only" types need to
-	// be written to by relocations and putting them in a section called
-	// ".rodata" interacts poorly with the system linkers. The GNU linkers
-	// support this situation by arranging for sections of the name
-	// ".data.rel.ro.XXX" to be mprotected read only by the dynamic linker after
-	// relocations have applied, so when the Go linker is creating a shared
-	// object it checks all objects of the above types and bumps any object that
-	// has a relocation to it to the corresponding type below, which are then
-	// written to sections with appropriate magic names.
-	STYPERELRO
-	SSTRINGRELRO
-	SGOSTRINGRELRO
-	SGOFUNCRELRO
-	SGCBITSRELRO
-	SRODATARELRO
-	SFUNCTABRELRO
-
-	// Part of .data.rel.ro if it exists, otherwise part of .rodata.
-	STYPELINK
-	SITABLINK
-	SSYMTAB
-	SPCLNTAB
-
-	// Writable sections.
-	SFirstWritable
-	SBUILDINFO
-	SELFSECT
-	SMACHO
-	SMACHOGOT
-	SWINDOWS
-	SELFGOT
-	SNOPTRDATA
-	SINITARR
-	SDATA
-	SXCOFFTOC
-	SBSS
-	SNOPTRBSS
-	SLIBFUZZER_EXTRA_COUNTER
-	STLSBSS
-	SXREF
-	SMACHOSYMSTR
-	SMACHOSYMTAB
-	SMACHOINDIRECTPLT
-	SMACHOINDIRECTGOT
-	SFILEPATH
-	SCONST
-	SDYNIMPORT
-	SHOSTOBJ
-	SUNDEFEXT // Undefined symbol for resolution by external linker
-
-	// Sections for debugging information
-	SDWARFSECT
-	SDWARFINFO
-	SDWARFRANGE
-	SDWARFLOC
-	SDWARFLINES
-
-	// ABI aliases (these never appear in the output)
-	SABIALIAS
-)
-
-// AbiSymKindToSymKind maps values read from object files (which are
-// of type cmd/internal/objabi.SymKind) to values of type SymKind.
-var AbiSymKindToSymKind = [...]SymKind{
-	Sxxx,
-	STEXT,
-	SRODATA,
-	SNOPTRDATA,
-	SDATA,
-	SBSS,
-	SNOPTRBSS,
-	STLSBSS,
-	SDWARFINFO,
-	SDWARFRANGE,
-	SDWARFLOC,
-	SDWARFLINES,
-	SABIALIAS,
-	SLIBFUZZER_EXTRA_COUNTER,
-}
-
-// ReadOnly are the symbol kinds that form read-only sections. In some
-// cases, if they will require relocations, they are transformed into
-// rel-ro sections using relROMap.
-var ReadOnly = []SymKind{
-	STYPE,
-	SSTRING,
-	SGOSTRING,
-	SGOFUNC,
-	SGCBITS,
-	SRODATA,
-	SFUNCTAB,
-}
-
-// RelROMap describes the transformation of read-only symbols to rel-ro
-// symbols.
-var RelROMap = map[SymKind]SymKind{
-	STYPE:     STYPERELRO,
-	SSTRING:   SSTRINGRELRO,
-	SGOSTRING: SGOSTRINGRELRO,
-	SGOFUNC:   SGOFUNCRELRO,
-	SGCBITS:   SGCBITSRELRO,
-	SRODATA:   SRODATARELRO,
-	SFUNCTAB:  SFUNCTABRELRO,
-}
-
-// IsData returns true if the type is a data type.
-func (t SymKind) IsData() bool {
-	return t == SDATA || t == SNOPTRDATA || t == SBSS || t == SNOPTRBSS
-}
diff --git a/src/cmd/oldlink/internal/sym/symkind_string.go b/src/cmd/oldlink/internal/sym/symkind_string.go
deleted file mode 100644
index 97af992..0000000
--- a/src/cmd/oldlink/internal/sym/symkind_string.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Code generated by "stringer -type=SymKind symkind.go"; DO NOT EDIT.
-
-package sym
-
-import "strconv"
-
-func _() {
-	// An "invalid array index" compiler error signifies that the constant values have changed.
-	// Re-run the stringer command to generate them again.
-	var x [1]struct{}
-	_ = x[Sxxx-0]
-	_ = x[STEXT-1]
-	_ = x[SELFRXSECT-2]
-	_ = x[STYPE-3]
-	_ = x[SSTRING-4]
-	_ = x[SGOSTRING-5]
-	_ = x[SGOFUNC-6]
-	_ = x[SGCBITS-7]
-	_ = x[SRODATA-8]
-	_ = x[SFUNCTAB-9]
-	_ = x[SELFROSECT-10]
-	_ = x[SMACHOPLT-11]
-	_ = x[STYPERELRO-12]
-	_ = x[SSTRINGRELRO-13]
-	_ = x[SGOSTRINGRELRO-14]
-	_ = x[SGOFUNCRELRO-15]
-	_ = x[SGCBITSRELRO-16]
-	_ = x[SRODATARELRO-17]
-	_ = x[SFUNCTABRELRO-18]
-	_ = x[STYPELINK-19]
-	_ = x[SITABLINK-20]
-	_ = x[SSYMTAB-21]
-	_ = x[SPCLNTAB-22]
-	_ = x[SFirstWritable-23]
-	_ = x[SBUILDINFO-24]
-	_ = x[SELFSECT-25]
-	_ = x[SMACHO-26]
-	_ = x[SMACHOGOT-27]
-	_ = x[SWINDOWS-28]
-	_ = x[SELFGOT-29]
-	_ = x[SNOPTRDATA-30]
-	_ = x[SINITARR-31]
-	_ = x[SDATA-32]
-	_ = x[SXCOFFTOC-33]
-	_ = x[SBSS-34]
-	_ = x[SNOPTRBSS-35]
-	_ = x[SLIBFUZZER_EXTRA_COUNTER-36]
-	_ = x[STLSBSS-37]
-	_ = x[SXREF-38]
-	_ = x[SMACHOSYMSTR-39]
-	_ = x[SMACHOSYMTAB-40]
-	_ = x[SMACHOINDIRECTPLT-41]
-	_ = x[SMACHOINDIRECTGOT-42]
-	_ = x[SFILEPATH-43]
-	_ = x[SCONST-44]
-	_ = x[SDYNIMPORT-45]
-	_ = x[SHOSTOBJ-46]
-	_ = x[SUNDEFEXT-47]
-	_ = x[SDWARFSECT-48]
-	_ = x[SDWARFINFO-49]
-	_ = x[SDWARFRANGE-50]
-	_ = x[SDWARFLOC-51]
-	_ = x[SDWARFLINES-52]
-	_ = x[SABIALIAS-53]
-}
-
-const _SymKind_name = "SxxxSTEXTSELFRXSECTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSMACHOPLTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSFirstWritableSBUILDINFOSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASXCOFFTOCSBSSSNOPTRBSSSLIBFUZZER_EXTRA_COUNTERSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILEPATHSCONSTSDYNIMPORTSHOSTOBJSUNDEFEXTSDWARFSECTSDWARFINFOSDWARFRANGESDWARFLOCSDWARFLINESSABIALIAS"
-
-var _SymKind_index = [...]uint16{0, 4, 9, 19, 24, 31, 40, 47, 54, 61, 69, 79, 88, 98, 110, 124, 136, 148, 160, 173, 182, 191, 198, 206, 220, 230, 238, 244, 253, 261, 268, 278, 286, 291, 300, 304, 313, 337, 344, 349, 361, 373, 390, 407, 416, 422, 432, 440, 449, 459, 469, 480, 489, 500, 509}
-
-func (i SymKind) String() string {
-	if i >= SymKind(len(_SymKind_index)-1) {
-		return "SymKind(" + strconv.FormatInt(int64(i), 10) + ")"
-	}
-	return _SymKind_name[_SymKind_index[i]:_SymKind_index[i+1]]
-}
diff --git a/src/cmd/oldlink/internal/wasm/asm.go b/src/cmd/oldlink/internal/wasm/asm.go
deleted file mode 100644
index 35bc7b1..0000000
--- a/src/cmd/oldlink/internal/wasm/asm.go
+++ /dev/null
@@ -1,583 +0,0 @@
-// Copyright 2018 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 wasm
-
-import (
-	"bytes"
-	"cmd/internal/objabi"
-	"cmd/oldlink/internal/ld"
-	"cmd/oldlink/internal/sym"
-	"io"
-	"regexp"
-)
-
-const (
-	I32 = 0x7F
-	I64 = 0x7E
-	F32 = 0x7D
-	F64 = 0x7C
-)
-
-const (
-	sectionCustom   = 0
-	sectionType     = 1
-	sectionImport   = 2
-	sectionFunction = 3
-	sectionTable    = 4
-	sectionMemory   = 5
-	sectionGlobal   = 6
-	sectionExport   = 7
-	sectionStart    = 8
-	sectionElement  = 9
-	sectionCode     = 10
-	sectionData     = 11
-)
-
-// funcValueOffset is the offset between the PC_F value of a function and the index of the function in WebAssembly
-const funcValueOffset = 0x1000 // TODO(neelance): make function addresses play nice with heap addresses
-
-func gentext(ctxt *ld.Link) {
-}
-
-type wasmFunc struct {
-	Name string
-	Type uint32
-	Code []byte
-}
-
-type wasmFuncType struct {
-	Params  []byte
-	Results []byte
-}
-
-var wasmFuncTypes = map[string]*wasmFuncType{
-	"_rt0_wasm_js":           {Params: []byte{}},                                         //
-	"wasm_export_run":        {Params: []byte{I32, I32}},                                 // argc, argv
-	"wasm_export_resume":     {Params: []byte{}},                                         //
-	"wasm_export_getsp":      {Results: []byte{I32}},                                     // sp
-	"wasm_pc_f_loop":         {Params: []byte{}},                                         //
-	"runtime.wasmMove":       {Params: []byte{I32, I32, I32}},                            // dst, src, len
-	"runtime.wasmZero":       {Params: []byte{I32, I32}},                                 // ptr, len
-	"runtime.wasmDiv":        {Params: []byte{I64, I64}, Results: []byte{I64}},           // x, y -> x/y
-	"runtime.wasmTruncS":     {Params: []byte{F64}, Results: []byte{I64}},                // x -> int(x)
-	"runtime.wasmTruncU":     {Params: []byte{F64}, Results: []byte{I64}},                // x -> uint(x)
-	"runtime.gcWriteBarrier": {Params: []byte{I64, I64}},                                 // ptr, val
-	"cmpbody":                {Params: []byte{I64, I64, I64, I64}, Results: []byte{I64}}, // a, alen, b, blen -> -1/0/1
-	"memeqbody":              {Params: []byte{I64, I64, I64}, Results: []byte{I64}},      // a, b, len -> 0/1
-	"memcmp":                 {Params: []byte{I32, I32, I32}, Results: []byte{I32}},      // a, b, len -> <0/0/>0
-	"memchr":                 {Params: []byte{I32, I32, I32}, Results: []byte{I32}},      // s, c, len -> index
-}
-
-func assignAddress(ctxt *ld.Link, sect *sym.Section, n int, s *sym.Symbol, va uint64, isTramp bool) (*sym.Section, int, uint64) {
-	// WebAssembly functions do not live in the same address space as the linear memory.
-	// Instead, WebAssembly automatically assigns indices. Imported functions (section "import")
-	// have indices 0 to n. They are followed by native functions (sections "function" and "code")
-	// with indices n+1 and following.
-	//
-	// The following rules describe how wasm handles function indices and addresses:
-	//   PC_F = funcValueOffset + WebAssembly function index (not including the imports)
-	//   s.Value = PC = PC_F<<16 + PC_B
-	//
-	// The funcValueOffset is necessary to avoid conflicts with expectations
-	// that the Go runtime has about function addresses.
-	// The field "s.Value" corresponds to the concept of PC at runtime.
-	// However, there is no PC register, only PC_F and PC_B. PC_F denotes the function,
-	// PC_B the resume point inside of that function. The entry of the function has PC_B = 0.
-	s.Sect = sect
-	s.Value = int64(funcValueOffset+va/ld.MINFUNC) << 16 // va starts at zero
-	va += uint64(ld.MINFUNC)
-	return sect, n, va
-}
-
-func asmb(ctxt *ld.Link) {} // dummy
-
-// asmb writes the final WebAssembly module binary.
-// Spec: https://webassembly.github.io/spec/core/binary/modules.html
-func asmb2(ctxt *ld.Link) {
-	types := []*wasmFuncType{
-		// For normal Go functions, the single parameter is PC_B,
-		// the return value is
-		// 0 if the function returned normally or
-		// 1 if the stack needs to be unwound.
-		{Params: []byte{I32}, Results: []byte{I32}},
-	}
-
-	// collect host imports (functions that get imported from the WebAssembly host, usually JavaScript)
-	hostImports := []*wasmFunc{
-		{
-			Name: "debug",
-			Type: lookupType(&wasmFuncType{Params: []byte{I32}}, &types),
-		},
-	}
-	hostImportMap := make(map[*sym.Symbol]int64)
-	for _, fn := range ctxt.Textp {
-		for _, r := range fn.R {
-			if r.Type == objabi.R_WASMIMPORT {
-				hostImportMap[r.Sym] = int64(len(hostImports))
-				hostImports = append(hostImports, &wasmFunc{
-					Name: r.Sym.Name,
-					Type: lookupType(&wasmFuncType{Params: []byte{I32}}, &types),
-				})
-			}
-		}
-	}
-
-	// collect functions with WebAssembly body
-	var buildid []byte
-	fns := make([]*wasmFunc, len(ctxt.Textp))
-	for i, fn := range ctxt.Textp {
-		wfn := new(bytes.Buffer)
-		if fn.Name == "go.buildid" {
-			writeUleb128(wfn, 0) // number of sets of locals
-			writeI32Const(wfn, 0)
-			wfn.WriteByte(0x0b) // end
-			buildid = fn.P
-		} else {
-			// Relocations have variable length, handle them here.
-			off := int32(0)
-			for _, r := range fn.R {
-				wfn.Write(fn.P[off:r.Off])
-				off = r.Off
-				switch r.Type {
-				case objabi.R_ADDR:
-					writeSleb128(wfn, r.Sym.Value+r.Add)
-				case objabi.R_CALL:
-					writeSleb128(wfn, int64(len(hostImports))+r.Sym.Value>>16-funcValueOffset)
-				case objabi.R_WASMIMPORT:
-					writeSleb128(wfn, hostImportMap[r.Sym])
-				default:
-					ld.Errorf(fn, "bad reloc type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
-					continue
-				}
-			}
-			wfn.Write(fn.P[off:])
-		}
-
-		typ := uint32(0)
-		if sig, ok := wasmFuncTypes[fn.Name]; ok {
-			typ = lookupType(sig, &types)
-		}
-
-		name := nameRegexp.ReplaceAllString(fn.Name, "_")
-		fns[i] = &wasmFunc{Name: name, Type: typ, Code: wfn.Bytes()}
-	}
-
-	ctxt.Out.Write([]byte{0x00, 0x61, 0x73, 0x6d}) // magic
-	ctxt.Out.Write([]byte{0x01, 0x00, 0x00, 0x00}) // version
-
-	// Add any buildid early in the binary:
-	if len(buildid) != 0 {
-		writeBuildID(ctxt, buildid)
-	}
-
-	writeTypeSec(ctxt, types)
-	writeImportSec(ctxt, hostImports)
-	writeFunctionSec(ctxt, fns)
-	writeTableSec(ctxt, fns)
-	writeMemorySec(ctxt)
-	writeGlobalSec(ctxt)
-	writeExportSec(ctxt, len(hostImports))
-	writeElementSec(ctxt, uint64(len(hostImports)), uint64(len(fns)))
-	writeCodeSec(ctxt, fns)
-	writeDataSec(ctxt)
-	writeProducerSec(ctxt)
-	if !*ld.FlagS {
-		writeNameSec(ctxt, len(hostImports), fns)
-	}
-
-	ctxt.Out.Flush()
-}
-
-func lookupType(sig *wasmFuncType, types *[]*wasmFuncType) uint32 {
-	for i, t := range *types {
-		if bytes.Equal(sig.Params, t.Params) && bytes.Equal(sig.Results, t.Results) {
-			return uint32(i)
-		}
-	}
-	*types = append(*types, sig)
-	return uint32(len(*types) - 1)
-}
-
-func writeSecHeader(ctxt *ld.Link, id uint8) int64 {
-	ctxt.Out.WriteByte(id)
-	sizeOffset := ctxt.Out.Offset()
-	ctxt.Out.Write(make([]byte, 5)) // placeholder for length
-	return sizeOffset
-}
-
-func writeSecSize(ctxt *ld.Link, sizeOffset int64) {
-	endOffset := ctxt.Out.Offset()
-	ctxt.Out.SeekSet(sizeOffset)
-	writeUleb128FixedLength(ctxt.Out, uint64(endOffset-sizeOffset-5), 5)
-	ctxt.Out.SeekSet(endOffset)
-}
-
-func writeBuildID(ctxt *ld.Link, buildid []byte) {
-	sizeOffset := writeSecHeader(ctxt, sectionCustom)
-	writeName(ctxt.Out, "go.buildid")
-	ctxt.Out.Write(buildid)
-	writeSecSize(ctxt, sizeOffset)
-}
-
-// writeTypeSec writes the section that declares all function types
-// so they can be referenced by index.
-func writeTypeSec(ctxt *ld.Link, types []*wasmFuncType) {
-	sizeOffset := writeSecHeader(ctxt, sectionType)
-
-	writeUleb128(ctxt.Out, uint64(len(types)))
-
-	for _, t := range types {
-		ctxt.Out.WriteByte(0x60) // functype
-		writeUleb128(ctxt.Out, uint64(len(t.Params)))
-		for _, v := range t.Params {
-			ctxt.Out.WriteByte(byte(v))
-		}
-		writeUleb128(ctxt.Out, uint64(len(t.Results)))
-		for _, v := range t.Results {
-			ctxt.Out.WriteByte(byte(v))
-		}
-	}
-
-	writeSecSize(ctxt, sizeOffset)
-}
-
-// writeImportSec writes the section that lists the functions that get
-// imported from the WebAssembly host, usually JavaScript.
-func writeImportSec(ctxt *ld.Link, hostImports []*wasmFunc) {
-	sizeOffset := writeSecHeader(ctxt, sectionImport)
-
-	writeUleb128(ctxt.Out, uint64(len(hostImports))) // number of imports
-	for _, fn := range hostImports {
-		writeName(ctxt.Out, "go") // provided by the import object in wasm_exec.js
-		writeName(ctxt.Out, fn.Name)
-		ctxt.Out.WriteByte(0x00) // func import
-		writeUleb128(ctxt.Out, uint64(fn.Type))
-	}
-
-	writeSecSize(ctxt, sizeOffset)
-}
-
-// writeFunctionSec writes the section that declares the types of functions.
-// The bodies of these functions will later be provided in the "code" section.
-func writeFunctionSec(ctxt *ld.Link, fns []*wasmFunc) {
-	sizeOffset := writeSecHeader(ctxt, sectionFunction)
-
-	writeUleb128(ctxt.Out, uint64(len(fns)))
-	for _, fn := range fns {
-		writeUleb128(ctxt.Out, uint64(fn.Type))
-	}
-
-	writeSecSize(ctxt, sizeOffset)
-}
-
-// writeTableSec writes the section that declares tables. Currently there is only a single table
-// that is used by the CallIndirect operation to dynamically call any function.
-// The contents of the table get initialized by the "element" section.
-func writeTableSec(ctxt *ld.Link, fns []*wasmFunc) {
-	sizeOffset := writeSecHeader(ctxt, sectionTable)
-
-	numElements := uint64(funcValueOffset + len(fns))
-	writeUleb128(ctxt.Out, 1)           // number of tables
-	ctxt.Out.WriteByte(0x70)            // type: anyfunc
-	ctxt.Out.WriteByte(0x00)            // no max
-	writeUleb128(ctxt.Out, numElements) // min
-
-	writeSecSize(ctxt, sizeOffset)
-}
-
-// writeMemorySec writes the section that declares linear memories. Currently one linear memory is being used.
-// Linear memory always starts at address zero. More memory can be requested with the GrowMemory instruction.
-func writeMemorySec(ctxt *ld.Link) {
-	sizeOffset := writeSecHeader(ctxt, sectionMemory)
-
-	dataSection := ctxt.Syms.Lookup("runtime.data", 0).Sect
-	dataEnd := dataSection.Vaddr + dataSection.Length
-	var initialSize = dataEnd + 16<<20 // 16MB, enough for runtime init without growing
-
-	const wasmPageSize = 64 << 10 // 64KB
-
-	writeUleb128(ctxt.Out, 1)                        // number of memories
-	ctxt.Out.WriteByte(0x00)                         // no maximum memory size
-	writeUleb128(ctxt.Out, initialSize/wasmPageSize) // minimum (initial) memory size
-
-	writeSecSize(ctxt, sizeOffset)
-}
-
-// writeGlobalSec writes the section that declares global variables.
-func writeGlobalSec(ctxt *ld.Link) {
-	sizeOffset := writeSecHeader(ctxt, sectionGlobal)
-
-	globalRegs := []byte{
-		I32, // 0: SP
-		I64, // 1: CTXT
-		I64, // 2: g
-		I64, // 3: RET0
-		I64, // 4: RET1
-		I64, // 5: RET2
-		I64, // 6: RET3
-		I32, // 7: PAUSE
-	}
-
-	writeUleb128(ctxt.Out, uint64(len(globalRegs))) // number of globals
-
-	for _, typ := range globalRegs {
-		ctxt.Out.WriteByte(typ)
-		ctxt.Out.WriteByte(0x01) // var
-		switch typ {
-		case I32:
-			writeI32Const(ctxt.Out, 0)
-		case I64:
-			writeI64Const(ctxt.Out, 0)
-		}
-		ctxt.Out.WriteByte(0x0b) // end
-	}
-
-	writeSecSize(ctxt, sizeOffset)
-}
-
-// writeExportSec writes the section that declares exports.
-// Exports can be accessed by the WebAssembly host, usually JavaScript.
-// The wasm_export_* functions and the linear memory get exported.
-func writeExportSec(ctxt *ld.Link, lenHostImports int) {
-	sizeOffset := writeSecHeader(ctxt, sectionExport)
-
-	writeUleb128(ctxt.Out, 4) // number of exports
-
-	for _, name := range []string{"run", "resume", "getsp"} {
-		idx := uint32(lenHostImports) + uint32(ctxt.Syms.ROLookup("wasm_export_"+name, 0).Value>>16) - funcValueOffset
-		writeName(ctxt.Out, name)           // inst.exports.run/resume/getsp in wasm_exec.js
-		ctxt.Out.WriteByte(0x00)            // func export
-		writeUleb128(ctxt.Out, uint64(idx)) // funcidx
-	}
-
-	writeName(ctxt.Out, "mem") // inst.exports.mem in wasm_exec.js
-	ctxt.Out.WriteByte(0x02)   // mem export
-	writeUleb128(ctxt.Out, 0)  // memidx
-
-	writeSecSize(ctxt, sizeOffset)
-}
-
-// writeElementSec writes the section that initializes the tables declared by the "table" section.
-// The table for CallIndirect gets initialized in a very simple way so that each table index (PC_F value)
-// maps linearly to the function index (numImports + PC_F).
-func writeElementSec(ctxt *ld.Link, numImports, numFns uint64) {
-	sizeOffset := writeSecHeader(ctxt, sectionElement)
-
-	writeUleb128(ctxt.Out, 1) // number of element segments
-
-	writeUleb128(ctxt.Out, 0) // tableidx
-	writeI32Const(ctxt.Out, funcValueOffset)
-	ctxt.Out.WriteByte(0x0b) // end
-
-	writeUleb128(ctxt.Out, numFns) // number of entries
-	for i := uint64(0); i < numFns; i++ {
-		writeUleb128(ctxt.Out, numImports+i)
-	}
-
-	writeSecSize(ctxt, sizeOffset)
-}
-
-// writeElementSec writes the section that provides the function bodies for the functions
-// declared by the "func" section.
-func writeCodeSec(ctxt *ld.Link, fns []*wasmFunc) {
-	sizeOffset := writeSecHeader(ctxt, sectionCode)
-
-	writeUleb128(ctxt.Out, uint64(len(fns))) // number of code entries
-	for _, fn := range fns {
-		writeUleb128(ctxt.Out, uint64(len(fn.Code)))
-		ctxt.Out.Write(fn.Code)
-	}
-
-	writeSecSize(ctxt, sizeOffset)
-}
-
-// writeDataSec writes the section that provides data that will be used to initialize the linear memory.
-func writeDataSec(ctxt *ld.Link) {
-	sizeOffset := writeSecHeader(ctxt, sectionData)
-
-	sections := []*sym.Section{
-		ctxt.Syms.Lookup("runtime.rodata", 0).Sect,
-		ctxt.Syms.Lookup("runtime.typelink", 0).Sect,
-		ctxt.Syms.Lookup("runtime.itablink", 0).Sect,
-		ctxt.Syms.Lookup("runtime.symtab", 0).Sect,
-		ctxt.Syms.Lookup("runtime.pclntab", 0).Sect,
-		ctxt.Syms.Lookup("runtime.noptrdata", 0).Sect,
-		ctxt.Syms.Lookup("runtime.data", 0).Sect,
-	}
-
-	type dataSegment struct {
-		offset int32
-		data   []byte
-	}
-
-	// Omit blocks of zeroes and instead emit data segments with offsets skipping the zeroes.
-	// This reduces the size of the WebAssembly binary. We use 8 bytes as an estimate for the
-	// overhead of adding a new segment (same as wasm-opt's memory-packing optimization uses).
-	const segmentOverhead = 8
-
-	// Generate at most this many segments. A higher number of segments gets rejected by some WebAssembly runtimes.
-	const maxNumSegments = 100000
-
-	var segments []*dataSegment
-	for secIndex, sec := range sections {
-		data := ld.DatblkBytes(ctxt, int64(sec.Vaddr), int64(sec.Length))
-		offset := int32(sec.Vaddr)
-
-		// skip leading zeroes
-		for len(data) > 0 && data[0] == 0 {
-			data = data[1:]
-			offset++
-		}
-
-		for len(data) > 0 {
-			dataLen := int32(len(data))
-			var segmentEnd, zeroEnd int32
-			if len(segments)+(len(sections)-secIndex) == maxNumSegments {
-				segmentEnd = dataLen
-				zeroEnd = dataLen
-			} else {
-				for {
-					// look for beginning of zeroes
-					for segmentEnd < dataLen && data[segmentEnd] != 0 {
-						segmentEnd++
-					}
-					// look for end of zeroes
-					zeroEnd = segmentEnd
-					for zeroEnd < dataLen && data[zeroEnd] == 0 {
-						zeroEnd++
-					}
-					// emit segment if omitting zeroes reduces the output size
-					if zeroEnd-segmentEnd >= segmentOverhead || zeroEnd == dataLen {
-						break
-					}
-					segmentEnd = zeroEnd
-				}
-			}
-
-			segments = append(segments, &dataSegment{
-				offset: offset,
-				data:   data[:segmentEnd],
-			})
-			data = data[zeroEnd:]
-			offset += zeroEnd
-		}
-	}
-
-	writeUleb128(ctxt.Out, uint64(len(segments))) // number of data entries
-	for _, seg := range segments {
-		writeUleb128(ctxt.Out, 0) // memidx
-		writeI32Const(ctxt.Out, seg.offset)
-		ctxt.Out.WriteByte(0x0b) // end
-		writeUleb128(ctxt.Out, uint64(len(seg.data)))
-		ctxt.Out.Write(seg.data)
-	}
-
-	writeSecSize(ctxt, sizeOffset)
-}
-
-// writeProducerSec writes an optional section that reports the source language and compiler version.
-func writeProducerSec(ctxt *ld.Link) {
-	sizeOffset := writeSecHeader(ctxt, sectionCustom)
-	writeName(ctxt.Out, "producers")
-
-	writeUleb128(ctxt.Out, 2) // number of fields
-
-	writeName(ctxt.Out, "language")     // field name
-	writeUleb128(ctxt.Out, 1)           // number of values
-	writeName(ctxt.Out, "Go")           // value: name
-	writeName(ctxt.Out, objabi.Version) // value: version
-
-	writeName(ctxt.Out, "processed-by")   // field name
-	writeUleb128(ctxt.Out, 1)             // number of values
-	writeName(ctxt.Out, "Go cmd/compile") // value: name
-	writeName(ctxt.Out, objabi.Version)   // value: version
-
-	writeSecSize(ctxt, sizeOffset)
-}
-
-var nameRegexp = regexp.MustCompile(`[^\w\.]`)
-
-// writeNameSec writes an optional section that assigns names to the functions declared by the "func" section.
-// The names are only used by WebAssembly stack traces, debuggers and decompilers.
-// TODO(neelance): add symbol table of DATA symbols
-func writeNameSec(ctxt *ld.Link, firstFnIndex int, fns []*wasmFunc) {
-	sizeOffset := writeSecHeader(ctxt, sectionCustom)
-	writeName(ctxt.Out, "name")
-
-	sizeOffset2 := writeSecHeader(ctxt, 0x01) // function names
-	writeUleb128(ctxt.Out, uint64(len(fns)))
-	for i, fn := range fns {
-		writeUleb128(ctxt.Out, uint64(firstFnIndex+i))
-		writeName(ctxt.Out, fn.Name)
-	}
-	writeSecSize(ctxt, sizeOffset2)
-
-	writeSecSize(ctxt, sizeOffset)
-}
-
-type nameWriter interface {
-	io.ByteWriter
-	io.Writer
-}
-
-func writeI32Const(w io.ByteWriter, v int32) {
-	w.WriteByte(0x41) // i32.const
-	writeSleb128(w, int64(v))
-}
-
-func writeI64Const(w io.ByteWriter, v int64) {
-	w.WriteByte(0x42) // i64.const
-	writeSleb128(w, v)
-}
-
-func writeName(w nameWriter, name string) {
-	writeUleb128(w, uint64(len(name)))
-	w.Write([]byte(name))
-}
-
-func writeUleb128(w io.ByteWriter, v uint64) {
-	if v < 128 {
-		w.WriteByte(uint8(v))
-		return
-	}
-	more := true
-	for more {
-		c := uint8(v & 0x7f)
-		v >>= 7
-		more = v != 0
-		if more {
-			c |= 0x80
-		}
-		w.WriteByte(c)
-	}
-}
-
-func writeUleb128FixedLength(w io.ByteWriter, v uint64, length int) {
-	for i := 0; i < length; i++ {
-		c := uint8(v & 0x7f)
-		v >>= 7
-		if i < length-1 {
-			c |= 0x80
-		}
-		w.WriteByte(c)
-	}
-	if v != 0 {
-		panic("writeUleb128FixedLength: length too small")
-	}
-}
-
-func writeSleb128(w io.ByteWriter, v int64) {
-	more := true
-	for more {
-		c := uint8(v & 0x7f)
-		s := uint8(v & 0x40)
-		v >>= 7
-		more = !((v == 0 && s == 0) || (v == -1 && s != 0))
-		if more {
-			c |= 0x80
-		}
-		w.WriteByte(c)
-	}
-}
diff --git a/src/cmd/oldlink/internal/wasm/obj.go b/src/cmd/oldlink/internal/wasm/obj.go
deleted file mode 100644
index fdc9fb7..0000000
--- a/src/cmd/oldlink/internal/wasm/obj.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 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 wasm
-
-import (
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-	theArch := ld.Arch{
-		Funcalign: 16,
-		Maxalign:  32,
-		Minalign:  1,
-
-		Archinit:      archinit,
-		AssignAddress: assignAddress,
-		Asmb:          asmb,
-		Asmb2:         asmb2,
-		Gentext:       gentext,
-	}
-
-	return sys.ArchWasm, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-	if *ld.FlagRound == -1 {
-		*ld.FlagRound = 4096
-	}
-	if *ld.FlagTextAddr == -1 {
-		*ld.FlagTextAddr = 0
-	}
-}
diff --git a/src/cmd/oldlink/internal/x86/asm.go b/src/cmd/oldlink/internal/x86/asm.go
deleted file mode 100644
index e8e52f6..0000000
--- a/src/cmd/oldlink/internal/x86/asm.go
+++ /dev/null
@@ -1,699 +0,0 @@
-// Inferno utils/8l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/8l/asm.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package x86
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-	"cmd/oldlink/internal/sym"
-	"debug/elf"
-	"log"
-)
-
-// Append 4 bytes to s and create a R_CALL relocation targeting t to fill them in.
-func addcall(ctxt *ld.Link, s *sym.Symbol, t *sym.Symbol) {
-	s.Attr |= sym.AttrReachable
-	i := s.Size
-	s.Size += 4
-	s.Grow(s.Size)
-	r := s.AddRel()
-	r.Sym = t
-	r.Off = int32(i)
-	r.Type = objabi.R_CALL
-	r.Siz = 4
-}
-
-func gentext(ctxt *ld.Link) {
-	if ctxt.DynlinkingGo() {
-		// We need get_pc_thunk.
-	} else {
-		switch ctxt.BuildMode {
-		case ld.BuildModeCArchive:
-			if !ctxt.IsELF {
-				return
-			}
-		case ld.BuildModePIE, ld.BuildModeCShared, ld.BuildModePlugin:
-			// We need get_pc_thunk.
-		default:
-			return
-		}
-	}
-
-	// Generate little thunks that load the PC of the next instruction into a register.
-	thunks := make([]*sym.Symbol, 0, 7+len(ctxt.Textp))
-	for _, r := range [...]struct {
-		name string
-		num  uint8
-	}{
-		{"ax", 0},
-		{"cx", 1},
-		{"dx", 2},
-		{"bx", 3},
-		// sp
-		{"bp", 5},
-		{"si", 6},
-		{"di", 7},
-	} {
-		thunkfunc := ctxt.Syms.Lookup("__x86.get_pc_thunk."+r.name, 0)
-		thunkfunc.Type = sym.STEXT
-		thunkfunc.Attr |= sym.AttrLocal
-		thunkfunc.Attr |= sym.AttrReachable //TODO: remove?
-		o := func(op ...uint8) {
-			for _, op1 := range op {
-				thunkfunc.AddUint8(op1)
-			}
-		}
-		// 8b 04 24	mov    (%esp),%eax
-		// Destination register is in bits 3-5 of the middle byte, so add that in.
-		o(0x8b, 0x04+r.num<<3, 0x24)
-		// c3		ret
-		o(0xc3)
-
-		thunks = append(thunks, thunkfunc)
-	}
-	ctxt.Textp = append(thunks, ctxt.Textp...) // keep Textp in dependency order
-
-	addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-	if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
-		// we're linking a module containing the runtime -> no need for
-		// an init function
-		return
-	}
-
-	addmoduledata.Attr |= sym.AttrReachable
-
-	initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-	initfunc.Type = sym.STEXT
-	initfunc.Attr |= sym.AttrLocal
-	initfunc.Attr |= sym.AttrReachable
-	o := func(op ...uint8) {
-		for _, op1 := range op {
-			initfunc.AddUint8(op1)
-		}
-	}
-
-	// go.link.addmoduledata:
-	//      53                      push %ebx
-	//      e8 00 00 00 00          call __x86.get_pc_thunk.cx + R_CALL __x86.get_pc_thunk.cx
-	//      8d 81 00 00 00 00       lea 0x0(%ecx), %eax + R_PCREL ctxt.Moduledata
-	//      8d 99 00 00 00 00       lea 0x0(%ecx), %ebx + R_GOTPC _GLOBAL_OFFSET_TABLE_
-	//      e8 00 00 00 00          call runtime.addmoduledata@plt + R_CALL runtime.addmoduledata
-	//      5b                      pop %ebx
-	//      c3                      ret
-
-	o(0x53)
-
-	o(0xe8)
-	addcall(ctxt, initfunc, ctxt.Syms.Lookup("__x86.get_pc_thunk.cx", 0))
-
-	o(0x8d, 0x81)
-	initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata, 6)
-
-	o(0x8d, 0x99)
-	i := initfunc.Size
-	initfunc.Size += 4
-	initfunc.Grow(initfunc.Size)
-	r := initfunc.AddRel()
-	r.Sym = ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
-	r.Off = int32(i)
-	r.Type = objabi.R_PCREL
-	r.Add = 12
-	r.Siz = 4
-
-	o(0xe8)
-	addcall(ctxt, initfunc, addmoduledata)
-
-	o(0x5b)
-
-	o(0xc3)
-
-	if ctxt.BuildMode == ld.BuildModePlugin {
-		ctxt.Textp = append(ctxt.Textp, addmoduledata)
-	}
-	ctxt.Textp = append(ctxt.Textp, initfunc)
-	initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-	initarray_entry.Attr |= sym.AttrReachable
-	initarray_entry.Attr |= sym.AttrLocal
-	initarray_entry.Type = sym.SINITARR
-	initarray_entry.AddAddr(ctxt.Arch, initfunc)
-}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-	targ := r.Sym
-
-	switch r.Type {
-	default:
-		if r.Type >= objabi.ElfRelocOffset {
-			ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
-			return false
-		}
-
-		// Handle relocations found in ELF object files.
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_PC32):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected R_386_PC32 relocation for dynamic symbol %s", targ.Name)
-		}
-		// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
-		// sense and should be removed when someone has thought about it properly.
-		if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
-			ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
-		}
-		r.Type = objabi.R_PCREL
-		r.Add += 4
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_PLT32):
-		r.Type = objabi.R_PCREL
-		r.Add += 4
-		if targ.Type == sym.SDYNIMPORT {
-			addpltsym(ctxt, targ)
-			r.Sym = ctxt.Syms.Lookup(".plt", 0)
-			r.Add += int64(targ.Plt())
-		}
-
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_GOT32),
-		objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_GOT32X):
-		if targ.Type != sym.SDYNIMPORT {
-			// have symbol
-			if r.Off >= 2 && s.P[r.Off-2] == 0x8b {
-				// turn MOVL of GOT entry into LEAL of symbol address, relative to GOT.
-				s.P[r.Off-2] = 0x8d
-
-				r.Type = objabi.R_GOTOFF
-				return true
-			}
-
-			if r.Off >= 2 && s.P[r.Off-2] == 0xff && s.P[r.Off-1] == 0xb3 {
-				// turn PUSHL of GOT entry into PUSHL of symbol itself.
-				// use unnecessary SS prefix to keep instruction same length.
-				s.P[r.Off-2] = 0x36
-
-				s.P[r.Off-1] = 0x68
-				r.Type = objabi.R_ADDR
-				return true
-			}
-
-			ld.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
-			return false
-		}
-
-		addgotsym(ctxt, targ)
-		r.Type = objabi.R_CONST // write r->add during relocsym
-		r.Sym = nil
-		r.Add += int64(targ.Got())
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_GOTOFF):
-		r.Type = objabi.R_GOTOFF
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_GOTPC):
-		r.Type = objabi.R_PCREL
-		r.Sym = ctxt.Syms.Lookup(".got", 0)
-		r.Add += 4
-		return true
-
-	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_32):
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected R_386_32 relocation for dynamic symbol %s", targ.Name)
-		}
-		r.Type = objabi.R_ADDR
-		return true
-
-	case objabi.MachoRelocOffset + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 0:
-		r.Type = objabi.R_ADDR
-		if targ.Type == sym.SDYNIMPORT {
-			ld.Errorf(s, "unexpected reloc for dynamic symbol %s", targ.Name)
-		}
-		return true
-
-	case objabi.MachoRelocOffset + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 1:
-		if targ.Type == sym.SDYNIMPORT {
-			addpltsym(ctxt, targ)
-			r.Sym = ctxt.Syms.Lookup(".plt", 0)
-			r.Add = int64(targ.Plt())
-			r.Type = objabi.R_PCREL
-			return true
-		}
-
-		r.Type = objabi.R_PCREL
-		return true
-
-	case objabi.MachoRelocOffset + ld.MACHO_FAKE_GOTPCREL:
-		if targ.Type != sym.SDYNIMPORT {
-			// have symbol
-			// turn MOVL of GOT entry into LEAL of symbol itself
-			if r.Off < 2 || s.P[r.Off-2] != 0x8b {
-				ld.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
-				return false
-			}
-
-			s.P[r.Off-2] = 0x8d
-			r.Type = objabi.R_PCREL
-			return true
-		}
-
-		addgotsym(ctxt, targ)
-		r.Sym = ctxt.Syms.Lookup(".got", 0)
-		r.Add += int64(targ.Got())
-		r.Type = objabi.R_PCREL
-		return true
-	}
-
-	// Handle references to ELF symbols from our own object files.
-	if targ.Type != sym.SDYNIMPORT {
-		return true
-	}
-	switch r.Type {
-	case objabi.R_CALL,
-		objabi.R_PCREL:
-		if ctxt.LinkMode == ld.LinkExternal {
-			// External linker will do this relocation.
-			return true
-		}
-		addpltsym(ctxt, targ)
-		r.Sym = ctxt.Syms.Lookup(".plt", 0)
-		r.Add = int64(targ.Plt())
-		return true
-
-	case objabi.R_ADDR:
-		if s.Type != sym.SDATA {
-			break
-		}
-		if ctxt.IsELF {
-			ld.Adddynsym(ctxt, targ)
-			rel := ctxt.Syms.Lookup(".rel", 0)
-			rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
-			rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_386_32)))
-			r.Type = objabi.R_CONST // write r->add during relocsym
-			r.Sym = nil
-			return true
-		}
-
-		if ctxt.HeadType == objabi.Hdarwin && s.Size == int64(ctxt.Arch.PtrSize) && r.Off == 0 {
-			// Mach-O relocations are a royal pain to lay out.
-			// They use a compact stateful bytecode representation
-			// that is too much bother to deal with.
-			// Instead, interpret the C declaration
-			//	void *_Cvar_stderr = &stderr;
-			// as making _Cvar_stderr the name of a GOT entry
-			// for stderr. This is separate from the usual GOT entry,
-			// just in case the C code assigns to the variable,
-			// and of course it only works for single pointers,
-			// but we only need to support cgo and that's all it needs.
-			ld.Adddynsym(ctxt, targ)
-
-			got := ctxt.Syms.Lookup(".got", 0)
-			s.Type = got.Type
-			s.Attr |= sym.AttrSubSymbol
-			s.Outer = got
-			s.Sub = got.Sub
-			got.Sub = s
-			s.Value = got.Size
-			got.AddUint32(ctxt.Arch, 0)
-			ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(targ.Dynid))
-			r.Type = objabi.ElfRelocOffset // ignore during relocsym
-			return true
-		}
-	}
-
-	return false
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-	ctxt.Out.Write32(uint32(sectoff))
-
-	elfsym := r.Xsym.ElfsymForReloc()
-	switch r.Type {
-	default:
-		return false
-	case objabi.R_ADDR:
-		if r.Siz == 4 {
-			ctxt.Out.Write32(uint32(elf.R_386_32) | uint32(elfsym)<<8)
-		} else {
-			return false
-		}
-	case objabi.R_GOTPCREL:
-		if r.Siz == 4 {
-			ctxt.Out.Write32(uint32(elf.R_386_GOTPC))
-			if r.Xsym.Name != "_GLOBAL_OFFSET_TABLE_" {
-				ctxt.Out.Write32(uint32(sectoff))
-				ctxt.Out.Write32(uint32(elf.R_386_GOT32) | uint32(elfsym)<<8)
-			}
-		} else {
-			return false
-		}
-	case objabi.R_CALL:
-		if r.Siz == 4 {
-			if r.Xsym.Type == sym.SDYNIMPORT {
-				ctxt.Out.Write32(uint32(elf.R_386_PLT32) | uint32(elfsym)<<8)
-			} else {
-				ctxt.Out.Write32(uint32(elf.R_386_PC32) | uint32(elfsym)<<8)
-			}
-		} else {
-			return false
-		}
-	case objabi.R_PCREL:
-		if r.Siz == 4 {
-			ctxt.Out.Write32(uint32(elf.R_386_PC32) | uint32(elfsym)<<8)
-		} else {
-			return false
-		}
-	case objabi.R_TLS_LE:
-		if r.Siz == 4 {
-			ctxt.Out.Write32(uint32(elf.R_386_TLS_LE) | uint32(elfsym)<<8)
-		} else {
-			return false
-		}
-	case objabi.R_TLS_IE:
-		if r.Siz == 4 {
-			ctxt.Out.Write32(uint32(elf.R_386_GOTPC))
-			ctxt.Out.Write32(uint32(sectoff))
-			ctxt.Out.Write32(uint32(elf.R_386_TLS_GOTIE) | uint32(elfsym)<<8)
-		} else {
-			return false
-		}
-	}
-
-	return true
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-	return false
-}
-
-func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-	var v uint32
-
-	rs := r.Xsym
-
-	if rs.Dynid < 0 {
-		ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
-		return false
-	}
-
-	out.Write32(uint32(sectoff))
-	out.Write32(uint32(rs.Dynid))
-
-	switch r.Type {
-	default:
-		return false
-
-	case objabi.R_DWARFSECREF:
-		v = ld.IMAGE_REL_I386_SECREL
-
-	case objabi.R_ADDR:
-		v = ld.IMAGE_REL_I386_DIR32
-
-	case objabi.R_CALL,
-		objabi.R_PCREL:
-		v = ld.IMAGE_REL_I386_REL32
-	}
-
-	out.Write16(uint16(v))
-
-	return true
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-	if ctxt.LinkMode == ld.LinkExternal {
-		return val, false
-	}
-	switch r.Type {
-	case objabi.R_CONST:
-		return r.Add, true
-	case objabi.R_GOTOFF:
-		return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
-	}
-
-	return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-	log.Fatalf("unexpected relocation variant")
-	return t
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-	plt := ctxt.Syms.Lookup(".plt", 0)
-	got := ctxt.Syms.Lookup(".got.plt", 0)
-	if plt.Size == 0 {
-		// pushl got+4
-		plt.AddUint8(0xff)
-
-		plt.AddUint8(0x35)
-		plt.AddAddrPlus(ctxt.Arch, got, 4)
-
-		// jmp *got+8
-		plt.AddUint8(0xff)
-
-		plt.AddUint8(0x25)
-		plt.AddAddrPlus(ctxt.Arch, got, 8)
-
-		// zero pad
-		plt.AddUint32(ctxt.Arch, 0)
-
-		// assume got->size == 0 too
-		got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
-
-		got.AddUint32(ctxt.Arch, 0)
-		got.AddUint32(ctxt.Arch, 0)
-	}
-}
-
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
-	if s.Plt() >= 0 {
-		return
-	}
-
-	ld.Adddynsym(ctxt, s)
-
-	if ctxt.IsELF {
-		plt := ctxt.Syms.Lookup(".plt", 0)
-		got := ctxt.Syms.Lookup(".got.plt", 0)
-		rel := ctxt.Syms.Lookup(".rel.plt", 0)
-		if plt.Size == 0 {
-			elfsetupplt(ctxt)
-		}
-
-		// jmpq *got+size
-		plt.AddUint8(0xff)
-
-		plt.AddUint8(0x25)
-		plt.AddAddrPlus(ctxt.Arch, got, got.Size)
-
-		// add to got: pointer to current pos in plt
-		got.AddAddrPlus(ctxt.Arch, plt, plt.Size)
-
-		// pushl $x
-		plt.AddUint8(0x68)
-
-		plt.AddUint32(ctxt.Arch, uint32(rel.Size))
-
-		// jmp .plt
-		plt.AddUint8(0xe9)
-
-		plt.AddUint32(ctxt.Arch, uint32(-(plt.Size + 4)))
-
-		// rel
-		rel.AddAddrPlus(ctxt.Arch, got, got.Size-4)
-
-		rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_JMP_SLOT)))
-
-		s.SetPlt(int32(plt.Size - 16))
-	} else if ctxt.HeadType == objabi.Hdarwin {
-		// Same laziness as in 6l.
-
-		plt := ctxt.Syms.Lookup(".plt", 0)
-
-		addgotsym(ctxt, s)
-
-		ctxt.Syms.Lookup(".linkedit.plt", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
-
-		// jmpq *got+size(IP)
-		s.SetPlt(int32(plt.Size))
-
-		plt.AddUint8(0xff)
-		plt.AddUint8(0x25)
-		plt.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got()))
-	} else {
-		ld.Errorf(s, "addpltsym: unsupported binary format")
-	}
-}
-
-func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
-	if s.Got() >= 0 {
-		return
-	}
-
-	ld.Adddynsym(ctxt, s)
-	got := ctxt.Syms.Lookup(".got", 0)
-	s.SetGot(int32(got.Size))
-	got.AddUint32(ctxt.Arch, 0)
-
-	if ctxt.IsELF {
-		rel := ctxt.Syms.Lookup(".rel", 0)
-		rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
-		rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_GLOB_DAT)))
-	} else if ctxt.HeadType == objabi.Hdarwin {
-		ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
-	} else {
-		ld.Errorf(s, "addgotsym: unsupported binary format")
-	}
-}
-
-func asmb(ctxt *ld.Link) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	sect := ld.Segtext.Sections[0]
-	ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-	// 0xCC is INT $3 - breakpoint instruction
-	ld.CodeblkPad(ctxt, int64(sect.Vaddr), int64(sect.Length), []byte{0xCC})
-	for _, sect = range ld.Segtext.Sections[1:] {
-		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-		ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-	}
-	if ld.Segrelrodata.Filelen > 0 {
-		ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
-		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
-	}
-
-	ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-	ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-	machlink := uint32(0)
-	if ctxt.HeadType == objabi.Hdarwin {
-		machlink = uint32(ld.Domacholink(ctxt))
-	}
-
-	ld.Symsize = 0
-	ld.Spsize = 0
-	ld.Lcsize = 0
-	symo := uint32(0)
-	if !*ld.FlagS {
-		// TODO: rationalize
-		switch ctxt.HeadType {
-		default:
-			if ctxt.IsELF {
-				symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-				symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
-			}
-
-		case objabi.Hplan9:
-			symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
-
-		case objabi.Hdarwin:
-			symo = uint32(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(*ld.FlagRound))) + uint64(machlink))
-
-		case objabi.Hwindows:
-			symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-			symo = uint32(ld.Rnd(int64(symo), ld.PEFILEALIGN))
-		}
-
-		ctxt.Out.SeekSet(int64(symo))
-		switch ctxt.HeadType {
-		default:
-			if ctxt.IsELF {
-				ld.Asmelfsym(ctxt)
-				ctxt.Out.Flush()
-				ctxt.Out.Write(ld.Elfstrdat)
-
-				if ctxt.LinkMode == ld.LinkExternal {
-					ld.Elfemitreloc(ctxt)
-				}
-			}
-
-		case objabi.Hplan9:
-			ld.Asmplan9sym(ctxt)
-			ctxt.Out.Flush()
-
-			sym := ctxt.Syms.Lookup("pclntab", 0)
-			if sym != nil {
-				ld.Lcsize = int32(len(sym.P))
-				ctxt.Out.Write(sym.P)
-				ctxt.Out.Flush()
-			}
-
-		case objabi.Hwindows:
-			// Do nothing
-
-		case objabi.Hdarwin:
-			if ctxt.LinkMode == ld.LinkExternal {
-				ld.Machoemitreloc(ctxt)
-			}
-		}
-	}
-
-	ctxt.Out.SeekSet(0)
-	switch ctxt.HeadType {
-	default:
-	case objabi.Hplan9: /* plan9 */
-		magic := int32(4*11*11 + 7)
-
-		ctxt.Out.Write32b(uint32(magic))              /* magic */
-		ctxt.Out.Write32b(uint32(ld.Segtext.Filelen)) /* sizes */
-		ctxt.Out.Write32b(uint32(ld.Segdata.Filelen))
-		ctxt.Out.Write32b(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-		ctxt.Out.Write32b(uint32(ld.Symsize))          /* nsyms */
-		ctxt.Out.Write32b(uint32(ld.Entryvalue(ctxt))) /* va of entry */
-		ctxt.Out.Write32b(uint32(ld.Spsize))           /* sp offsets */
-		ctxt.Out.Write32b(uint32(ld.Lcsize))           /* line offsets */
-
-	case objabi.Hdarwin:
-		ld.Asmbmacho(ctxt)
-
-	case objabi.Hlinux,
-		objabi.Hfreebsd,
-		objabi.Hnetbsd,
-		objabi.Hopenbsd:
-		ld.Asmbelf(ctxt, int64(symo))
-
-	case objabi.Hwindows:
-		ld.Asmbpe(ctxt)
-	}
-
-	ctxt.Out.Flush()
-}
diff --git a/src/cmd/oldlink/internal/x86/l.go b/src/cmd/oldlink/internal/x86/l.go
deleted file mode 100644
index 0f104ea..0000000
--- a/src/cmd/oldlink/internal/x86/l.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Inferno utils/8l/l.h
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/8l/l.h
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package x86
-
-const (
-	maxAlign  = 32 // max data alignment
-	minAlign  = 1  // min data alignment
-	funcAlign = 16
-)
-
-/* Used by ../internal/ld/dwarf.go */
-const (
-	dwarfRegSP = 4
-	dwarfRegLR = 8
-)
diff --git a/src/cmd/oldlink/internal/x86/obj.go b/src/cmd/oldlink/internal/x86/obj.go
deleted file mode 100644
index b78ccba..0000000
--- a/src/cmd/oldlink/internal/x86/obj.go
+++ /dev/null
@@ -1,113 +0,0 @@
-// Inferno utils/8l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/8l/obj.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package x86
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-	arch := sys.Arch386
-
-	theArch := ld.Arch{
-		Funcalign:  funcAlign,
-		Maxalign:   maxAlign,
-		Minalign:   minAlign,
-		Dwarfregsp: dwarfRegSP,
-		Dwarfreglr: dwarfRegLR,
-
-		Adddynrel:        adddynrel,
-		Archinit:         archinit,
-		Archreloc:        archreloc,
-		Archrelocvariant: archrelocvariant,
-		Asmb:             asmb,
-		Asmb2:            asmb2,
-		Elfreloc1:        elfreloc1,
-		Elfsetupplt:      elfsetupplt,
-		Gentext:          gentext,
-		Machoreloc1:      machoreloc1,
-		PEreloc1:         pereloc1,
-
-		Linuxdynld:   "/lib/ld-linux.so.2",
-		Freebsddynld: "/usr/libexec/ld-elf.so.1",
-		Openbsddynld: "/usr/libexec/ld.so",
-		Netbsddynld:  "/usr/libexec/ld.elf_so",
-		Solarisdynld: "/lib/ld.so.1",
-	}
-
-	return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-	switch ctxt.HeadType {
-	default:
-		ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-
-	case objabi.Hplan9: /* plan 9 */
-		ld.HEADR = 32
-
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 4096 + int64(ld.HEADR)
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 4096
-		}
-
-	case objabi.Hdarwin: /* apple MACH */
-		ld.HEADR = ld.INITIAL_MACHO_HEADR
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 4096 + int64(ld.HEADR)
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 4096
-		}
-
-	case objabi.Hlinux, /* elf32 executable */
-		objabi.Hfreebsd,
-		objabi.Hnetbsd,
-		objabi.Hopenbsd:
-		ld.Elfinit(ctxt)
-
-		ld.HEADR = ld.ELFRESERVE
-		if *ld.FlagTextAddr == -1 {
-			*ld.FlagTextAddr = 0x08048000 + int64(ld.HEADR)
-		}
-		if *ld.FlagRound == -1 {
-			*ld.FlagRound = 4096
-		}
-
-	case objabi.Hwindows: /* PE executable */
-		// ld.HEADR, ld.FlagTextAddr, ld.FlagRound are set in ld.Peinit
-		return
-	}
-}
diff --git a/src/cmd/oldlink/main.go b/src/cmd/oldlink/main.go
deleted file mode 100644
index be1d0fd..0000000
--- a/src/cmd/oldlink/main.go
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(go115newobj): delete.
-
-package main
-
-import (
-	"cmd/internal/objabi"
-	"cmd/internal/sys"
-	"cmd/oldlink/internal/amd64"
-	"cmd/oldlink/internal/arm"
-	"cmd/oldlink/internal/arm64"
-	"cmd/oldlink/internal/ld"
-	"cmd/oldlink/internal/mips"
-	"cmd/oldlink/internal/mips64"
-	"cmd/oldlink/internal/ppc64"
-	"cmd/oldlink/internal/riscv64"
-	"cmd/oldlink/internal/s390x"
-	"cmd/oldlink/internal/wasm"
-	"cmd/oldlink/internal/x86"
-	"fmt"
-	"os"
-)
-
-// The bulk of the linker implementation lives in cmd/oldlink/internal/ld.
-// Architecture-specific code lives in cmd/oldlink/internal/GOARCH.
-//
-// Program initialization:
-//
-// Before any argument parsing is done, the Init function of relevant
-// architecture package is called. The only job done in Init is
-// configuration of the architecture-specific variables.
-//
-// Then control flow passes to ld.Main, which parses flags, makes
-// some configuration decisions, and then gives the architecture
-// packages a second chance to modify the linker's configuration
-// via the ld.Arch.Archinit function.
-
-func main() {
-	var arch *sys.Arch
-	var theArch ld.Arch
-
-	switch objabi.GOARCH {
-	default:
-		fmt.Fprintf(os.Stderr, "link: unknown architecture %q\n", objabi.GOARCH)
-		os.Exit(2)
-	case "386":
-		arch, theArch = x86.Init()
-	case "amd64":
-		arch, theArch = amd64.Init()
-	case "arm":
-		arch, theArch = arm.Init()
-	case "arm64":
-		arch, theArch = arm64.Init()
-	case "mips", "mipsle":
-		arch, theArch = mips.Init()
-	case "mips64", "mips64le":
-		arch, theArch = mips64.Init()
-	case "ppc64", "ppc64le":
-		arch, theArch = ppc64.Init()
-	case "riscv64":
-		arch, theArch = riscv64.Init()
-	case "s390x":
-		arch, theArch = s390x.Init()
-	case "wasm":
-		arch, theArch = wasm.Init()
-	}
-	ld.Main(arch, theArch)
-}
