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..31d8549 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:
@@ -97,8 +96,8 @@
 		}
 	}
 	if ok && !*flags.SymABIs {
-		ctxt.NumberSyms(true)
-		obj.WriteObjFile(ctxt, buf, "")
+		ctxt.NumberSyms()
+		obj.WriteObjFile(ctxt, buf, *flags.Importpath)
 	}
 	if !ok || diag {
 		if failedFile != "" {
diff --git a/src/cmd/compile/internal/gc/iexport.go b/src/cmd/compile/internal/gc/iexport.go
index 35b8d98..328260f 100644
--- a/src/cmd/compile/internal/gc/iexport.go
+++ b/src/cmd/compile/internal/gc/iexport.go
@@ -207,6 +207,7 @@
 	"cmd/compile/internal/types"
 	"cmd/internal/goobj2"
 	"cmd/internal/src"
+	"crypto/md5"
 	"encoding/binary"
 	"fmt"
 	"io"
@@ -295,12 +296,15 @@
 	hdr.uint64(dataLen)
 
 	// Flush output.
-	io.Copy(out, &hdr)
-	io.Copy(out, &p.strings)
-	io.Copy(out, &p.data0)
+	h := md5.New()
+	wr := io.MultiWriter(out, h)
+	io.Copy(wr, &hdr)
+	io.Copy(wr, &p.strings)
+	io.Copy(wr, &p.data0)
 
 	// Add fingerprint (used by linker object file).
 	// Attach this to the end, so tools (e.g. gcimporter) don't care.
+	copy(Ctxt.Fingerprint[:], h.Sum(nil)[:])
 	out.Write(Ctxt.Fingerprint[:])
 }
 
@@ -997,18 +1001,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 104b5fb..15a660c 100644
--- a/src/cmd/compile/internal/gc/iimport.go
+++ b/src/cmd/compile/internal/gc/iimport.go
@@ -697,16 +697,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..6e204f4 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
@@ -790,7 +789,7 @@
 	// Write object data to disk.
 	timings.Start("be", "dumpobj")
 	dumpdata()
-	Ctxt.NumberSyms(false)
+	Ctxt.NumberSyms()
 	dumpobj()
 	if asmhdr != "" {
 		dumpasmhdr()
@@ -1489,7 +1488,7 @@
 		return
 	}
 	s := Ctxt.Lookup(dwarf.CUInfoPrefix + "producer." + myimportpath)
-	s.Type = objabi.SDWARFINFO
+	s.Type = objabi.SDWARFCUINFO
 	// Sometimes (for example when building tests) we can link
 	// together two package main archives. So allow dups.
 	s.Set(obj.AttrDuplicateOK, true)
@@ -1501,7 +1500,7 @@
 // compiled, so that the linker can save it in the compile unit's DIE.
 func recordPackageName() {
 	s := Ctxt.Lookup(dwarf.CUInfoPrefix + "packagename." + myimportpath)
-	s.Type = objabi.SDWARFINFO
+	s.Type = objabi.SDWARFCUINFO
 	// Sometimes (for example when building tests) we can link
 	// together two package main archives. So allow dups.
 	s.Set(obj.AttrDuplicateOK, true)
diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go
index 74654c8..f80d0c1 100644
--- a/src/cmd/compile/internal/gc/pgen.go
+++ b/src/cmd/compile/internal/gc/pgen.go
@@ -428,9 +428,10 @@
 
 	decls, dwarfVars := createDwarfVars(fnsym, fn.Func, apdecls)
 
-	// For each type referenced by the functions auto vars, attach a
-	// dummy relocation to the function symbol to insure that the type
-	// included in DWARF processing during linking.
+	// For each type referenced by the functions auto vars but not
+	// already referenced by a dwarf var, attach a dummy relocation to
+	// the function symbol to insure that the type included in DWARF
+	// processing during linking.
 	typesyms := []*obj.LSym{}
 	for t, _ := range fnsym.Func.Autot {
 		typesyms = append(typesyms, t)
@@ -480,7 +481,7 @@
 
 // createSimpleVars creates a DWARF entry for every variable declared in the
 // function, claiming that they are permanently on the stack.
-func createSimpleVars(apDecls []*Node) ([]*Node, []*dwarf.Var, map[*Node]bool) {
+func createSimpleVars(fnsym *obj.LSym, apDecls []*Node) ([]*Node, []*dwarf.Var, map[*Node]bool) {
 	var vars []*dwarf.Var
 	var decls []*Node
 	selected := make(map[*Node]bool)
@@ -490,13 +491,13 @@
 		}
 
 		decls = append(decls, n)
-		vars = append(vars, createSimpleVar(n))
+		vars = append(vars, createSimpleVar(fnsym, n))
 		selected[n] = true
 	}
 	return decls, vars, selected
 }
 
-func createSimpleVar(n *Node) *dwarf.Var {
+func createSimpleVar(fnsym *obj.LSym, n *Node) *dwarf.Var {
 	var abbrev int
 	offs := n.Xoffset
 
@@ -519,6 +520,7 @@
 	}
 
 	typename := dwarf.InfoPrefix + typesymname(n.Type)
+	delete(fnsym.Func.Autot, ngotype(n).Linksym())
 	inlIndex := 0
 	if genDwarfInline > 1 {
 		if n.Name.InlFormal() || n.Name.InlLocal() {
@@ -546,7 +548,7 @@
 
 // createComplexVars creates recomposed DWARF vars with location lists,
 // suitable for describing optimized code.
-func createComplexVars(fn *Func) ([]*Node, []*dwarf.Var, map[*Node]bool) {
+func createComplexVars(fnsym *obj.LSym, fn *Func) ([]*Node, []*dwarf.Var, map[*Node]bool) {
 	debugInfo := fn.DebugInfo
 
 	// Produce a DWARF variable entry for each user variable.
@@ -561,7 +563,7 @@
 			ssaVars[debugInfo.Slots[slot].N.(*Node)] = true
 		}
 
-		if dvar := createComplexVar(fn, ssa.VarID(varID)); dvar != nil {
+		if dvar := createComplexVar(fnsym, fn, ssa.VarID(varID)); dvar != nil {
 			decls = append(decls, n)
 			vars = append(vars, dvar)
 		}
@@ -578,9 +580,9 @@
 	var decls []*Node
 	var selected map[*Node]bool
 	if Ctxt.Flag_locationlists && Ctxt.Flag_optimize && fn.DebugInfo != nil {
-		decls, vars, selected = createComplexVars(fn)
+		decls, vars, selected = createComplexVars(fnsym, fn)
 	} else {
-		decls, vars, selected = createSimpleVars(apDecls)
+		decls, vars, selected = createSimpleVars(fnsym, apDecls)
 	}
 
 	dcl := apDecls
@@ -616,7 +618,7 @@
 			// Args not of SSA-able type are treated here; they
 			// are homed on the stack in a single place for the
 			// entire call.
-			vars = append(vars, createSimpleVar(n))
+			vars = append(vars, createSimpleVar(fnsym, n))
 			decls = append(decls, n)
 			continue
 		}
@@ -712,7 +714,7 @@
 }
 
 // createComplexVar builds a single DWARF variable entry and location list.
-func createComplexVar(fn *Func, varID ssa.VarID) *dwarf.Var {
+func createComplexVar(fnsym *obj.LSym, fn *Func, varID ssa.VarID) *dwarf.Var {
 	debug := fn.DebugInfo
 	n := debug.Vars[varID].(*Node)
 
@@ -727,6 +729,7 @@
 	}
 
 	gotype := ngotype(n).Linksym()
+	delete(fnsym.Func.Autot, gotype)
 	typename := dwarf.InfoPrefix + gotype.Name[len("type."):]
 	inlIndex := 0
 	if genDwarfInline > 1 {
diff --git a/src/cmd/internal/dwarf/dwarf.go b/src/cmd/internal/dwarf/dwarf.go
index a17b574..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."
@@ -398,9 +386,9 @@
 
 // Abbrevs() returns the finalized abbrev array for the platform,
 // expanding any DW_FORM pseudo-ops to real values.
-func Abbrevs() [DW_NABRV]dwAbbrev {
+func Abbrevs() []dwAbbrev {
 	if abbrevsFinalized {
-		return abbrevs
+		return abbrevs[:]
 	}
 	for i := 1; i < DW_NABRV; i++ {
 		for j := 0; j < len(abbrevs[i].attr); j++ {
@@ -408,7 +396,7 @@
 		}
 	}
 	abbrevsFinalized = true
-	return abbrevs
+	return abbrevs[:]
 }
 
 // abbrevs is a raw table of abbrev entries; it needs to be post-processed
diff --git a/src/cmd/internal/goobj/readnew.go b/src/cmd/internal/goobj/readnew.go
index 7a84b91..cd1a904 100644
--- a/src/cmd/internal/goobj/readnew.go
+++ b/src/cmd/internal/goobj/readnew.go
@@ -48,7 +48,7 @@
 	}
 
 	resolveSymRef := func(s goobj2.SymRef) SymID {
-		var i int
+		var i uint32
 		switch p := s.PkgIdx; p {
 		case goobj2.PkgIdxInvalid:
 			if s.SymIdx != 0 {
@@ -56,12 +56,12 @@
 			}
 			return SymID{}
 		case goobj2.PkgIdxNone:
-			i = int(s.SymIdx) + rr.NSym()
+			i = s.SymIdx + uint32(rr.NSym())
 		case goobj2.PkgIdxBuiltin:
 			name, abi := goobj2.BuiltinName(int(s.SymIdx))
 			return SymID{name, int64(abi)}
 		case goobj2.PkgIdxSelf:
-			i = int(s.SymIdx)
+			i = s.SymIdx
 		default:
 			return SymID{refNames[s], 0}
 		}
@@ -73,9 +73,9 @@
 
 	// Symbols
 	pcdataBase := start + rr.PcdataBase()
-	n := rr.NSym() + rr.NNonpkgdef() + rr.NNonpkgref()
-	ndef := rr.NSym() + rr.NNonpkgdef()
-	for i := 0; i < n; i++ {
+	n := uint32(rr.NSym() + rr.NNonpkgdef() + rr.NNonpkgref())
+	ndef := uint32(rr.NSym() + rr.NNonpkgdef())
+	for i := uint32(0); i < n; i++ {
 		osym := rr.Sym(i)
 		if osym.Name(rr) == "" {
 			continue // not a real symbol
@@ -119,7 +119,7 @@
 		}
 
 		// Aux symbol info
-		isym := -1
+		isym := ^uint32(0)
 		funcdata := make([]goobj2.SymRef, 0, 4)
 		auxs := rr.Auxs(i)
 		for j := range auxs {
@@ -131,7 +131,7 @@
 				if a.Sym().PkgIdx != goobj2.PkgIdxSelf {
 					panic("funcinfo symbol not defined in current package")
 				}
-				isym = int(a.Sym().SymIdx)
+				isym = a.Sym().SymIdx
 			case goobj2.AuxFuncdata:
 				funcdata = append(funcdata, a.Sym())
 			case goobj2.AuxDwarfInfo, goobj2.AuxDwarfLoc, goobj2.AuxDwarfRanges, goobj2.AuxDwarfLines:
@@ -142,7 +142,7 @@
 		}
 
 		// Symbol Info
-		if isym == -1 {
+		if isym == ^uint32(0) {
 			continue
 		}
 		b := rr.BytesAt(rr.DataOff(isym), rr.DataSize(isym))
diff --git a/src/cmd/internal/goobj2/objfile.go b/src/cmd/internal/goobj2/objfile.go
index 7f728e4..3e6375b 100644
--- a/src/cmd/internal/goobj2/objfile.go
+++ b/src/cmd/internal/goobj2/objfile.go
@@ -238,7 +238,8 @@
 const SymABIstatic = ^uint16(0)
 
 const (
-	ObjFlagShared = 1 << iota
+	ObjFlagShared            = 1 << iota // this object is built with -shared
+	ObjFlagNeedNameExpansion             // the linker needs to expand `"".` to package path in symbol names
 )
 
 const (
@@ -619,83 +620,83 @@
 }
 
 // SymOff returns the offset of the i-th symbol.
-func (r *Reader) SymOff(i int) uint32 {
+func (r *Reader) SymOff(i uint32) uint32 {
 	return r.h.Offsets[BlkSymdef] + uint32(i*SymSize)
 }
 
 // Sym returns a pointer to the i-th symbol.
-func (r *Reader) Sym(i int) *Sym {
+func (r *Reader) Sym(i uint32) *Sym {
 	off := r.SymOff(i)
 	return (*Sym)(unsafe.Pointer(&r.b[off]))
 }
 
 // NReloc returns the number of relocations of the i-th symbol.
-func (r *Reader) NReloc(i int) int {
+func (r *Reader) NReloc(i uint32) int {
 	relocIdxOff := r.h.Offsets[BlkRelocIdx] + uint32(i*4)
 	return int(r.uint32At(relocIdxOff+4) - r.uint32At(relocIdxOff))
 }
 
 // RelocOff returns the offset of the j-th relocation of the i-th symbol.
-func (r *Reader) RelocOff(i int, j int) uint32 {
+func (r *Reader) RelocOff(i uint32, j int) uint32 {
 	relocIdxOff := r.h.Offsets[BlkRelocIdx] + uint32(i*4)
 	relocIdx := r.uint32At(relocIdxOff)
 	return r.h.Offsets[BlkReloc] + (relocIdx+uint32(j))*uint32(RelocSize)
 }
 
 // Reloc returns a pointer to the j-th relocation of the i-th symbol.
-func (r *Reader) Reloc(i int, j int) *Reloc {
+func (r *Reader) Reloc(i uint32, j int) *Reloc {
 	off := r.RelocOff(i, j)
 	return (*Reloc)(unsafe.Pointer(&r.b[off]))
 }
 
 // Relocs returns a pointer to the relocations of the i-th symbol.
-func (r *Reader) Relocs(i int) []Reloc {
+func (r *Reader) Relocs(i uint32) []Reloc {
 	off := r.RelocOff(i, 0)
 	n := r.NReloc(i)
 	return (*[1 << 20]Reloc)(unsafe.Pointer(&r.b[off]))[:n:n]
 }
 
 // NAux returns the number of aux symbols of the i-th symbol.
-func (r *Reader) NAux(i int) int {
-	auxIdxOff := r.h.Offsets[BlkAuxIdx] + uint32(i*4)
+func (r *Reader) NAux(i uint32) int {
+	auxIdxOff := r.h.Offsets[BlkAuxIdx] + i*4
 	return int(r.uint32At(auxIdxOff+4) - r.uint32At(auxIdxOff))
 }
 
 // AuxOff returns the offset of the j-th aux symbol of the i-th symbol.
-func (r *Reader) AuxOff(i int, j int) uint32 {
-	auxIdxOff := r.h.Offsets[BlkAuxIdx] + uint32(i*4)
+func (r *Reader) AuxOff(i uint32, j int) uint32 {
+	auxIdxOff := r.h.Offsets[BlkAuxIdx] + i*4
 	auxIdx := r.uint32At(auxIdxOff)
 	return r.h.Offsets[BlkAux] + (auxIdx+uint32(j))*uint32(AuxSize)
 }
 
 // Aux returns a pointer to the j-th aux symbol of the i-th symbol.
-func (r *Reader) Aux(i int, j int) *Aux {
+func (r *Reader) Aux(i uint32, j int) *Aux {
 	off := r.AuxOff(i, j)
 	return (*Aux)(unsafe.Pointer(&r.b[off]))
 }
 
 // Auxs returns the aux symbols of the i-th symbol.
-func (r *Reader) Auxs(i int) []Aux {
+func (r *Reader) Auxs(i uint32) []Aux {
 	off := r.AuxOff(i, 0)
 	n := r.NAux(i)
 	return (*[1 << 20]Aux)(unsafe.Pointer(&r.b[off]))[:n:n]
 }
 
 // DataOff returns the offset of the i-th symbol's data.
-func (r *Reader) DataOff(i int) uint32 {
-	dataIdxOff := r.h.Offsets[BlkDataIdx] + uint32(i*4)
+func (r *Reader) DataOff(i uint32) uint32 {
+	dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4
 	return r.h.Offsets[BlkData] + r.uint32At(dataIdxOff)
 }
 
 // DataSize returns the size of the i-th symbol's data.
-func (r *Reader) DataSize(i int) int {
-	dataIdxOff := r.h.Offsets[BlkDataIdx] + uint32(i*4)
+func (r *Reader) DataSize(i uint32) int {
+	dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4
 	return int(r.uint32At(dataIdxOff+4) - r.uint32At(dataIdxOff))
 }
 
 // Data returns the i-th symbol's data.
-func (r *Reader) Data(i int) []byte {
-	dataIdxOff := r.h.Offsets[BlkDataIdx] + uint32(i*4)
+func (r *Reader) Data(i uint32) []byte {
+	dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4
 	base := r.h.Offsets[BlkData]
 	off := r.uint32At(dataIdxOff)
 	end := r.uint32At(dataIdxOff + 4)
@@ -728,3 +729,6 @@
 func (r *Reader) Flags() uint32 {
 	return r.h.Flags
 }
+
+func (r *Reader) Shared() bool            { return r.Flags()&ObjFlagShared != 0 }
+func (r *Reader) NeedNameExpansion() bool { return r.Flags()&ObjFlagNeedNameExpansion != 0 }
diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go
index f860b93..d9628bf 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 93c3138..c0194c5 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.SDWARFFCN,
+		}
+		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)
@@ -659,7 +296,7 @@
 		return
 	}
 	s := ctxt.LookupInit(dwarf.ConstInfoPrefix+myimportpath, func(s *LSym) {
-		s.Type = objabi.SDWARFINFO
+		s.Type = objabi.SDWARFCONST
 		ctxt.Data = append(ctxt.Data, s)
 	})
 	dwarf.PutIntConst(dwCtxt{ctxt}, s, ctxt.Lookup(dwarf.InfoPrefix+typename), myimportpath+"."+name, val)
@@ -785,7 +422,7 @@
 	// the back end.
 	absfn := ft.ctxt.LookupDerived(s, dwarf.InfoPrefix+s.Name+dwarf.AbstractFuncSuffix)
 	absfn.Set(AttrDuplicateOK, true)
-	absfn.Type = objabi.SDWARFINFO
+	absfn.Type = objabi.SDWARFABSFCN
 	ft.ctxt.Data = append(ft.ctxt.Data, absfn)
 
 	// In the case of "late" inlining (inlines that happen during
diff --git a/src/cmd/internal/obj/objfile2.go b/src/cmd/internal/obj/objfile2.go
index 05400a1..591df09 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)
 
@@ -38,6 +38,9 @@
 	if ctxt.Flag_shared {
 		flags |= goobj2.ObjFlagShared
 	}
+	if pkgpath == "" {
+		flags |= goobj2.ObjFlagNeedNameExpansion
+	}
 	h := goobj2.Header{
 		Magic:       goobj2.Magic,
 		Fingerprint: ctxt.Fingerprint,
@@ -464,7 +467,8 @@
 	// Most aux symbols (ex: funcdata) are not interesting--
 	// pick out just the DWARF ones for now.
 	if aux.Type != objabi.SDWARFLOC &&
-		aux.Type != objabi.SDWARFINFO &&
+		aux.Type != objabi.SDWARFFCN &&
+		aux.Type != objabi.SDWARFABSFCN &&
 		aux.Type != objabi.SDWARFLINES &&
 		aux.Type != objabi.SDWARFRANGE {
 		return
diff --git a/src/cmd/internal/obj/plist.go b/src/cmd/internal/obj/plist.go
index 73b6e8b..d4f9089 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 400a741..bfc405c 100644
--- a/src/cmd/internal/obj/sym.go
+++ b/src/cmd/internal/obj/sym.go
@@ -34,7 +34,6 @@
 import (
 	"cmd/internal/goobj2"
 	"cmd/internal/objabi"
-	"crypto/md5"
 	"fmt"
 	"log"
 	"math"
@@ -164,11 +163,7 @@
 // Assign index to symbols.
 // 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
-	}
-
+func (ctxt *Link) NumberSyms() {
 	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
@@ -185,7 +180,7 @@
 
 	var idx, nonpkgidx int32 = 0, 0
 	ctxt.traverseSyms(traverseDefs, func(s *LSym) {
-		if isNonPkgSym(ctxt, asm, s) {
+		if isNonPkgSym(ctxt, s) {
 			s.PkgIdx = goobj2.PkgIdxNone
 			s.SymIdx = nonpkgidx
 			if nonpkgidx != int32(len(ctxt.nonpkgdefs)) {
@@ -242,21 +237,12 @@
 		ctxt.pkgIdx[pkg] = ipkg
 		ipkg++
 	})
-
-	// Compute a fingerprint of the indices, for exporting.
-	if !asm {
-		h := md5.New()
-		for _, s := range ctxt.defs {
-			h.Write([]byte(s.Name))
-		}
-		copy(ctxt.Fingerprint[:], h.Sum(nil)[:])
-	}
 }
 
 // Returns whether s is a non-package symbol, which needs to be referenced
 // by name instead of by index.
-func isNonPkgSym(ctxt *Link, asm bool, s *LSym) bool {
-	if asm && !s.Static() {
+func isNonPkgSym(ctxt *Link, s *LSym) bool {
+	if ctxt.IsAsm && !s.Static() {
 		// asm symbols are referenced by name only, except static symbols
 		// which are file-local and can be referenced by index.
 		return true
diff --git a/src/cmd/internal/objabi/symkind.go b/src/cmd/internal/objabi/symkind.go
index 374aaa6..6c99112 100644
--- a/src/cmd/internal/objabi/symkind.go
+++ b/src/cmd/internal/objabi/symkind.go
@@ -56,7 +56,12 @@
 	// Thread-local data that is initially all 0s
 	STLSBSS
 	// Debugging data
-	SDWARFINFO
+	SDWARFCUINFO
+	SDWARFCONST
+	SDWARFFCN
+	SDWARFABSFCN
+	SDWARFTYPE
+	SDWARFVAR
 	SDWARFRANGE
 	SDWARFLOC
 	SDWARFLINES
diff --git a/src/cmd/internal/objabi/symkind_string.go b/src/cmd/internal/objabi/symkind_string.go
index 919a666..1b1c394 100644
--- a/src/cmd/internal/objabi/symkind_string.go
+++ b/src/cmd/internal/objabi/symkind_string.go
@@ -16,17 +16,22 @@
 	_ = x[SBSS-5]
 	_ = x[SNOPTRBSS-6]
 	_ = x[STLSBSS-7]
-	_ = x[SDWARFINFO-8]
-	_ = x[SDWARFRANGE-9]
-	_ = x[SDWARFLOC-10]
-	_ = x[SDWARFLINES-11]
-	_ = x[SABIALIAS-12]
-	_ = x[SLIBFUZZER_EXTRA_COUNTER-13]
+	_ = x[SDWARFCUINFO-8]
+	_ = x[SDWARFCONST-9]
+	_ = x[SDWARFFCN-10]
+	_ = x[SDWARFABSFCN-11]
+	_ = x[SDWARFTYPE-12]
+	_ = x[SDWARFVAR-13]
+	_ = x[SDWARFRANGE-14]
+	_ = x[SDWARFLOC-15]
+	_ = x[SDWARFLINES-16]
+	_ = x[SABIALIAS-17]
+	_ = x[SLIBFUZZER_EXTRA_COUNTER-18]
 }
 
-const _SymKind_name = "SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFINFOSDWARFRANGESDWARFLOCSDWARFLINESSABIALIASSLIBFUZZER_EXTRA_COUNTER"
+const _SymKind_name = "SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINESSABIALIASSLIBFUZZER_EXTRA_COUNTER"
 
-var _SymKind_index = [...]uint8{0, 4, 9, 16, 26, 31, 35, 44, 51, 61, 72, 81, 92, 101, 125}
+var _SymKind_index = [...]uint8{0, 4, 9, 16, 26, 31, 35, 44, 51, 63, 74, 83, 95, 105, 114, 125, 134, 145, 154, 178}
 
 func (i SymKind) String() string {
 	if i >= SymKind(len(_SymKind_index)-1) {
diff --git a/src/cmd/link/dwarf_test.go b/src/cmd/link/dwarf_test.go
index 5926f09..326f493 100644
--- a/src/cmd/link/dwarf_test.go
+++ b/src/cmd/link/dwarf_test.go
@@ -191,6 +191,13 @@
 	if err := exec.Command("xcrun", "--help").Run(); err != nil {
 		t.Skipf("error running xcrun, required for iOS cross build: %v", err)
 	}
+	// Check to see if the ios tools are installed. It's possible to have the command line tools
+	// installed without the iOS sdk.
+	if output, err := exec.Command("xcodebuild -showsdks").CombinedOutput(); err != nil {
+		t.Skipf("error running xcodebuild, required for iOS cross build: %v", err)
+	} else if !strings.Contains(string(output), "iOS SDK") {
+		t.Skipf("iOS SDK not detected.")
+	}
 	cc := "CC=" + runtime.GOROOT() + "/misc/ios/clangwrap.sh"
 	// iOS doesn't allow unmapped segments, so iOS executables don't have DWARF.
 	testDWARF(t, "", false, cc, "CGO_ENABLED=1", "GOOS=darwin", "GOARCH=arm64")
diff --git a/src/cmd/link/internal/amd64/asm.go b/src/cmd/link/internal/amd64/asm.go
index b8dc0fc..659c03e 100644
--- a/src/cmd/link/internal/amd64/asm.go
+++ b/src/cmd/link/internal/amd64/asm.go
@@ -38,14 +38,13 @@
 	"cmd/link/internal/sym"
 	"debug/elf"
 	"log"
-	"sync"
 )
 
 func PADDR(x uint32) uint32 {
 	return x &^ 0x80000000
 }
 
-func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
+func gentext(ctxt *ld.Link, ldr *loader.Loader) {
 	initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt)
 	if initfunc == nil {
 		return
@@ -61,7 +60,7 @@
 	//    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.Moduledata2, 0)
+	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)
@@ -70,15 +69,7 @@
 	o(0xc3)
 }
 
-// makeWritable makes a readonly symbol writable if we do opcode rewriting.
-func makeWritable(s *sym.Symbol) {
-	if s.Attr.ReadOnly() {
-		s.Attr.Set(sym.AttrReadOnly, false)
-		s.P = append([]byte(nil), s.P...)
-	}
-}
-
-func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
+func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
 	targ := r.Sym()
 	var targType sym.SymKind
 	if targ != 0 {
@@ -124,8 +115,8 @@
 		su.SetRelocType(rIdx, objabi.R_PCREL)
 		su.SetRelocAdd(rIdx, r.Add()+4)
 		if targType == sym.SDYNIMPORT {
-			addpltsym2(target, ldr, syms, targ)
-			su.SetRelocSym(rIdx, syms.PLT2)
+			addpltsym(target, ldr, syms, targ)
+			su.SetRelocSym(rIdx, syms.PLT)
 			su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymPlt(targ)))
 		}
 
@@ -151,10 +142,10 @@
 
 		// fall back to using GOT and hope for the best (CMOV*)
 		// TODO: just needs relocation, no need to put in .dynsym
-		addgotsym2(target, ldr, syms, targ)
+		ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_X86_64_GLOB_DAT))
 
 		su.SetRelocType(rIdx, objabi.R_PCREL)
-		su.SetRelocSym(rIdx, syms.GOT2)
+		su.SetRelocSym(rIdx, syms.GOT)
 		su.SetRelocAdd(rIdx, r.Add()+4+int64(ldr.SymGot(targ)))
 		return true
 
@@ -187,9 +178,9 @@
 
 	case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_BRANCH*2 + 1:
 		if targType == sym.SDYNIMPORT {
-			addpltsym2(target, ldr, syms, targ)
+			addpltsym(target, ldr, syms, targ)
 			su := ldr.MakeSymbolUpdater(s)
-			su.SetRelocSym(rIdx, syms.PLT2)
+			su.SetRelocSym(rIdx, syms.PLT)
 			su.SetRelocType(rIdx, objabi.R_PCREL)
 			su.SetRelocAdd(rIdx, int64(ldr.SymPlt(targ)))
 			return true
@@ -232,10 +223,10 @@
 		if targType != sym.SDYNIMPORT {
 			ldr.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", ldr.SymName(targ))
 		}
-		addgotsym2(target, ldr, syms, targ)
+		ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_X86_64_GLOB_DAT))
 		su := ldr.MakeSymbolUpdater(s)
 		su.SetRelocType(rIdx, objabi.R_PCREL)
-		su.SetRelocSym(rIdx, syms.GOT2)
+		su.SetRelocSym(rIdx, syms.GOT)
 		su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
 		return true
 	}
@@ -257,9 +248,9 @@
 		}
 		// Internal linking, for both ELF and Mach-O.
 		// Build a PLT entry and change the relocation target to that entry.
-		addpltsym2(target, ldr, syms, targ)
+		addpltsym(target, ldr, syms, targ)
 		su := ldr.MakeSymbolUpdater(s)
-		su.SetRelocSym(rIdx, syms.PLT2)
+		su.SetRelocSym(rIdx, syms.PLT)
 		su.SetRelocAdd(rIdx, int64(ldr.SymPlt(targ)))
 		return true
 
@@ -267,17 +258,17 @@
 		if ldr.SymType(s) == sym.STEXT && target.IsElf() {
 			su := ldr.MakeSymbolUpdater(s)
 			if target.IsSolaris() {
-				addpltsym2(target, ldr, syms, targ)
-				su.SetRelocSym(rIdx, syms.PLT2)
+				addpltsym(target, ldr, syms, targ)
+				su.SetRelocSym(rIdx, syms.PLT)
 				su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymPlt(targ)))
 				return true
 			}
 			// The code is asking for the address of an external
 			// function. We provide it with the address of the
 			// correspondent GOT symbol.
-			addgotsym2(target, ldr, syms, targ)
+			ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_X86_64_GLOB_DAT))
 
-			su.SetRelocSym(rIdx, syms.GOT2)
+			su.SetRelocSym(rIdx, syms.GOT)
 			su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
 			return true
 		}
@@ -349,7 +340,7 @@
 			// 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 := ldr.MakeSymbolUpdater(syms.Rela2)
+			rela := ldr.MakeSymbolUpdater(syms.Rela)
 			rela.AddAddrPlus(target.Arch, s, int64(r.Off()))
 			if r.Siz() == 8 {
 				rela.AddUint64(target.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_X86_64_RELATIVE)))
@@ -375,15 +366,15 @@
 			// 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.Adddynsym2(ldr, target, syms, targ)
+			ld.Adddynsym(ldr, target, syms, targ)
 
-			got := ldr.MakeSymbolUpdater(syms.GOT2)
+			got := ldr.MakeSymbolUpdater(syms.GOT)
 			su := ldr.MakeSymbolUpdater(s)
 			su.SetType(got.Type())
 			got.PrependSub(s)
 			su.SetValue(got.Size())
 			got.AddUint64(target.Arch, 0)
-			leg := ldr.MakeSymbolUpdater(syms.LinkEditGOT2)
+			leg := ldr.MakeSymbolUpdater(syms.LinkEditGOT)
 			leg.AddUint32(target.Arch, uint32(ldr.SymDynid(targ)))
 			su.SetRelocType(rIdx, objabi.ElfRelocOffset) // ignore during relocsym
 			return true
@@ -393,12 +384,12 @@
 	return false
 }
 
-func elfreloc2(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
+func elfreloc1(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
 	ctxt.Out.Write64(uint64(sectoff))
 
-	xsym := ldr.Syms[r.Xsym]
-	elfsym := ld.ElfSymForReloc(ctxt, xsym)
+	elfsym := ld.ElfSymForReloc(ctxt, r.Xsym)
 	siz := r.Siz()
+	xst := ldr.SymType(r.Xsym)
 	switch r.Type() {
 	default:
 		return false
@@ -424,7 +415,7 @@
 		}
 	case objabi.R_CALL:
 		if siz == 4 {
-			if xsym.Type == sym.SDYNIMPORT {
+			if xst == sym.SDYNIMPORT {
 				if ctxt.DynlinkingGo() {
 					ctxt.Out.Write64(uint64(elf.R_X86_64_PLT32) | uint64(elfsym)<<32)
 				} else {
@@ -438,7 +429,7 @@
 		}
 	case objabi.R_PCREL:
 		if siz == 4 {
-			if xsym.Type == sym.SDYNIMPORT && xsym.ElfType() == elf.STT_FUNC {
+			if xst == sym.SDYNIMPORT && ldr.SymElfType(r.Xsym) == 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)
@@ -458,28 +449,29 @@
 	return true
 }
 
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
 	var v uint32
 
 	rs := r.Xsym
+	rt := r.Type()
 
-	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)
+	if ldr.SymType(rs) == sym.SHOSTOBJ || rt == objabi.R_PCREL || rt == objabi.R_GOTPCREL || rt == objabi.R_CALL {
+		if ldr.SymDynid(rs) < 0 {
+			ldr.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs))
 			return false
 		}
 
-		v = uint32(rs.Dynid)
+		v = uint32(ldr.SymDynid(rs))
 		v |= 1 << 27 // external relocation
 	} else {
-		v = uint32(rs.Sect.Extnum)
+		v = uint32(ldr.SymSect(rs).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)
+			ldr.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymSect(rs).Name, ldr.SymType(rs), ldr.SymType(rs))
 			return false
 		}
 	}
 
-	switch r.Type {
+	switch rt {
 	default:
 		return false
 
@@ -499,7 +491,7 @@
 		v |= ld.MACHO_X86_64_RELOC_GOT_LOAD << 28
 	}
 
-	switch r.Siz {
+	switch r.Siz() {
 	default:
 		return false
 
@@ -521,20 +513,21 @@
 	return true
 }
 
-func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+func pereloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
 	var v uint32
 
 	rs := r.Xsym
+	rt := r.Type()
 
-	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)
+	if ldr.SymDynid(rs) < 0 {
+		ldr.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs))
 		return false
 	}
 
 	out.Write32(uint32(sectoff))
-	out.Write32(uint32(rs.Dynid))
+	out.Write32(uint32(ldr.SymDynid(rs)))
 
-	switch r.Type {
+	switch rt {
 	default:
 		return false
 
@@ -542,7 +535,7 @@
 		v = ld.IMAGE_REL_AMD64_SECREL
 
 	case objabi.R_ADDR:
-		if r.Siz == 8 {
+		if r.Siz() == 8 {
 			v = ld.IMAGE_REL_AMD64_ADDR64
 		} else {
 			v = ld.IMAGE_REL_AMD64_ADDR32
@@ -558,13 +551,13 @@
 	return true
 }
 
-func archreloc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-	return val, false
+func archreloc(*ld.Target, *loader.Loader, *ld.ArchSyms, loader.Reloc2, *loader.ExtReloc, loader.Sym, int64) (int64, bool, bool) {
+	return -1, false, false
 }
 
-func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
+func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc2, sym.RelocVariant, loader.Sym, int64) int64 {
 	log.Fatalf("unexpected relocation variant")
-	return t
+	return -1
 }
 
 func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
@@ -592,17 +585,17 @@
 	}
 }
 
-func addpltsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
+func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
 	if ldr.SymPlt(s) >= 0 {
 		return
 	}
 
-	ld.Adddynsym2(ldr, target, syms, s)
+	ld.Adddynsym(ldr, target, syms, s)
 
 	if target.IsElf() {
-		plt := ldr.MakeSymbolUpdater(syms.PLT2)
-		got := ldr.MakeSymbolUpdater(syms.GOTPLT2)
-		rela := ldr.MakeSymbolUpdater(syms.RelaPLT2)
+		plt := ldr.MakeSymbolUpdater(syms.PLT)
+		got := ldr.MakeSymbolUpdater(syms.GOTPLT)
+		rela := ldr.MakeSymbolUpdater(syms.RelaPLT)
 		if plt.Size() == 0 {
 			panic("plt is not set up")
 		}
@@ -645,11 +638,11 @@
 		// https://networkpx.blogspot.com/2009/09/about-lcdyldinfoonly-command.html
 		// has details about what we're avoiding.
 
-		addgotsym2(target, ldr, syms, s)
-		plt := ldr.MakeSymbolUpdater(syms.PLT2)
+		ld.AddGotSym(target, ldr, syms, s, uint32(elf.R_X86_64_GLOB_DAT))
+		plt := ldr.MakeSymbolUpdater(syms.PLT)
 
 		sDynid := ldr.SymDynid(s)
-		lep := ldr.MakeSymbolUpdater(syms.LinkEditPLT2)
+		lep := ldr.MakeSymbolUpdater(syms.LinkEditPLT)
 		lep.AddUint32(target.Arch, uint32(sDynid))
 
 		// jmpq *got+size(IP)
@@ -657,192 +650,11 @@
 
 		plt.AddUint8(0xff)
 		plt.AddUint8(0x25)
-		plt.AddPCRelPlus(target.Arch, syms.GOT2, int64(ldr.SymGot(s)))
+		plt.AddPCRelPlus(target.Arch, syms.GOT, int64(ldr.SymGot(s)))
 	} else {
 		ldr.Errorf(s, "addpltsym: unsupported binary format")
 	}
 }
-
-func addgotsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
-	if ldr.SymGot(s) >= 0 {
-		return
-	}
-
-	ld.Adddynsym2(ldr, target, syms, s)
-	got := ldr.MakeSymbolUpdater(syms.GOT2)
-	ldr.SetGot(s, int32(got.Size()))
-	got.AddUint64(target.Arch, 0)
-
-	if target.IsElf() {
-		rela := ldr.MakeSymbolUpdater(syms.Rela2)
-		rela.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
-		rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(ldr.SymDynid(s)), uint32(elf.R_X86_64_GLOB_DAT)))
-		rela.AddUint64(target.Arch, 0)
-	} else if target.IsDarwin() {
-		leg := ldr.MakeSymbolUpdater(syms.LinkEditGOT2)
-		leg.AddUint32(target.Arch, uint32(ldr.SymDynid(s)))
-	} else {
-		ldr.Errorf(s, "addgotsym: unsupported binary format")
-	}
-}
-
-func asmb(ctxt *ld.Link, _ *loader.Loader) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	var wg sync.WaitGroup
-	sect := ld.Segtext.Sections[0]
-	offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-	f := func(ctxt *ld.Link, out *ld.OutBuf, start, length int64) {
-		// 0xCC is INT $3 - breakpoint instruction
-		ld.CodeblkPad(ctxt, out, start, length, []byte{0xCC})
-	}
-	ld.WriteParallel(&wg, f, ctxt, offset, sect.Vaddr, sect.Length)
-
-	for _, sect := range ld.Segtext.Sections[1:] {
-		offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, offset, sect.Vaddr, sect.Length)
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrodata.Fileoff, ld.Segrodata.Vaddr, ld.Segrodata.Filelen)
-	}
-
-	if ld.Segrelrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrelrodata.Fileoff, ld.Segrelrodata.Vaddr, ld.Segrelrodata.Filelen)
-	}
-
-	ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segdata.Fileoff, ld.Segdata.Vaddr, ld.Segdata.Filelen)
-
-	ld.WriteParallel(&wg, ld.Dwarfblk, ctxt, ld.Segdwarf.Fileoff, ld.Segdwarf.Vaddr, ld.Segdwarf.Filelen)
-
-	wg.Wait()
-}
-
-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.Write(ld.Elfstrdat)
-
-				if ctxt.LinkMode == ld.LinkExternal {
-					ld.Elfemitreloc(ctxt)
-				}
-			}
-
-		case objabi.Hplan9:
-			ld.Asmplan9sym(ctxt)
-
-			sym := ctxt.Syms.Lookup("pclntab", 0)
-			if sym != nil {
-				ld.Lcsize = int32(len(sym.P))
-				ctxt.Out.Write(sym.P)
-			}
-
-		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)
-	}
-}
-
 func tlsIEtoLE(P []byte, off, size int) {
 	// Transform the PC-relative instruction into a constant load.
 	// That is,
diff --git a/src/cmd/link/internal/amd64/obj.go b/src/cmd/link/internal/amd64/obj.go
index 705827d..4c52574 100644
--- a/src/cmd/link/internal/amd64/obj.go
+++ b/src/cmd/link/internal/amd64/obj.go
@@ -50,16 +50,19 @@
 		Minalign:   minAlign,
 		Dwarfregsp: dwarfRegSP,
 		Dwarfreglr: dwarfRegLR,
+		// 0xCC is INT $3 - breakpoint instruction
+		CodePad: []byte{0xCC},
 
-		Adddynrel2:       adddynrel2,
+		Plan9Magic:  uint32(4*26*26 + 7),
+		Plan9_64Bit: true,
+
+		Adddynrel:        adddynrel,
 		Archinit:         archinit,
 		Archreloc:        archreloc,
 		Archrelocvariant: archrelocvariant,
-		Asmb:             asmb,
-		Asmb2:            asmb2,
-		Elfreloc2:        elfreloc2,
+		Elfreloc1:        elfreloc1,
 		Elfsetupplt:      elfsetupplt,
-		Gentext2:         gentext2,
+		Gentext:          gentext,
 		Machoreloc1:      machoreloc1,
 		PEreloc1:         pereloc1,
 		TLSIEtoLE:        tlsIEtoLE,
diff --git a/src/cmd/link/internal/arm/asm.go b/src/cmd/link/internal/arm/asm.go
index 903e621..1f78f76 100644
--- a/src/cmd/link/internal/arm/asm.go
+++ b/src/cmd/link/internal/arm/asm.go
@@ -39,7 +39,6 @@
 	"debug/elf"
 	"fmt"
 	"log"
-	"sync"
 )
 
 // This assembler:
@@ -63,7 +62,7 @@
 //    c:        00000004        .word   0x00000004
 //                      c: R_ARM_GOT_PREL       local.moduledata
 
-func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
+func gentext(ctxt *ld.Link, ldr *loader.Loader) {
 	initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt)
 	if initfunc == nil {
 		return
@@ -91,7 +90,7 @@
 		Off:  12,
 		Size: 4,
 		Type: objabi.R_PCREL,
-		Sym:  ctxt.Moduledata2,
+		Sym:  ctxt.Moduledata,
 		Add:  4,
 	}
 	initfunc.AddReloc(rel2)
@@ -103,7 +102,7 @@
 	return int32((uint32(a))&0xff000000 | 0x00ffffff&uint32(a+b))
 }
 
-func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
+func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
 
 	targ := r.Sym()
 	var targType sym.SymKind
@@ -124,8 +123,8 @@
 		su.SetRelocType(rIdx, objabi.R_CALLARM)
 
 		if targType == sym.SDYNIMPORT {
-			addpltsym2(target, ldr, syms, targ)
-			su.SetRelocSym(rIdx, syms.PLT2)
+			addpltsym(target, ldr, syms, targ)
+			su.SetRelocSym(rIdx, syms.PLT)
 			su.SetRelocAdd(rIdx, int64(braddoff(int32(r.Add()), ldr.SymPlt(targ)/4)))
 		}
 
@@ -137,9 +136,9 @@
 
 	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOT32): // R_ARM_GOT_BREL
 		if targType != sym.SDYNIMPORT {
-			addgotsyminternal2(target, ldr, syms, targ)
+			addgotsyminternal(target, ldr, syms, targ)
 		} else {
-			addgotsym2(target, ldr, syms, targ)
+			ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_ARM_GLOB_DAT))
 		}
 
 		su := ldr.MakeSymbolUpdater(s)
@@ -150,13 +149,13 @@
 
 	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOT_PREL): // GOT(nil) + A - nil
 		if targType != sym.SDYNIMPORT {
-			addgotsyminternal2(target, ldr, syms, targ)
+			addgotsyminternal(target, ldr, syms, targ)
 		} else {
-			addgotsym2(target, ldr, syms, targ)
+			ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_ARM_GLOB_DAT))
 		}
 		su := ldr.MakeSymbolUpdater(s)
 		su.SetRelocType(rIdx, objabi.R_PCREL)
-		su.SetRelocSym(rIdx, syms.GOT2)
+		su.SetRelocSym(rIdx, syms.GOT)
 		su.SetRelocAdd(rIdx, r.Add()+4+int64(ldr.SymGot(targ)))
 		return true
 
@@ -168,7 +167,7 @@
 	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOTPC): // R_ARM_BASE_PREL
 		su := ldr.MakeSymbolUpdater(s)
 		su.SetRelocType(rIdx, objabi.R_PCREL)
-		su.SetRelocSym(rIdx, syms.GOT2)
+		su.SetRelocSym(rIdx, syms.GOT)
 		su.SetRelocAdd(rIdx, r.Add()+4)
 		return true
 
@@ -176,8 +175,8 @@
 		su := ldr.MakeSymbolUpdater(s)
 		su.SetRelocType(rIdx, objabi.R_CALLARM)
 		if targType == sym.SDYNIMPORT {
-			addpltsym2(target, ldr, syms, targ)
-			su.SetRelocSym(rIdx, syms.PLT2)
+			addpltsym(target, ldr, syms, targ)
+			su.SetRelocSym(rIdx, syms.PLT)
 			su.SetRelocAdd(rIdx, int64(braddoff(int32(r.Add()), ldr.SymPlt(targ)/4)))
 		}
 		return true
@@ -201,8 +200,8 @@
 		su := ldr.MakeSymbolUpdater(s)
 		su.SetRelocType(rIdx, objabi.R_CALLARM)
 		if targType == sym.SDYNIMPORT {
-			addpltsym2(target, ldr, syms, targ)
-			su.SetRelocSym(rIdx, syms.PLT2)
+			addpltsym(target, ldr, syms, targ)
+			su.SetRelocSym(rIdx, syms.PLT)
 			su.SetRelocAdd(rIdx, int64(braddoff(int32(r.Add()), ldr.SymPlt(targ)/4)))
 		}
 
@@ -224,9 +223,9 @@
 			// External linker will do this relocation.
 			return true
 		}
-		addpltsym2(target, ldr, syms, targ)
+		addpltsym(target, ldr, syms, targ)
 		su := ldr.MakeSymbolUpdater(s)
-		su.SetRelocSym(rIdx, syms.PLT2)
+		su.SetRelocSym(rIdx, syms.PLT)
 		su.SetRelocAdd(rIdx, int64(ldr.SymPlt(targ)))
 		return true
 
@@ -235,8 +234,8 @@
 			break
 		}
 		if target.IsElf() {
-			ld.Adddynsym2(ldr, target, syms, targ)
-			rel := ldr.MakeSymbolUpdater(syms.Rel2)
+			ld.Adddynsym(ldr, target, syms, targ)
+			rel := ldr.MakeSymbolUpdater(syms.Rel)
 			rel.AddAddrPlus(target.Arch, s, int64(r.Off()))
 			rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(ldr.SymDynid(targ)), uint32(elf.R_ARM_GLOB_DAT))) // we need a nil + A dynamic reloc
 			su := ldr.MakeSymbolUpdater(s)
@@ -249,28 +248,29 @@
 	return false
 }
 
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
+func elfreloc1(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
 	ctxt.Out.Write32(uint32(sectoff))
 
 	elfsym := ld.ElfSymForReloc(ctxt, r.Xsym)
-	switch r.Type {
+	siz := r.Siz()
+	switch r.Type() {
 	default:
 		return false
 	case objabi.R_ADDR, objabi.R_DWARFSECREF:
-		if r.Siz == 4 {
+		if siz == 4 {
 			ctxt.Out.Write32(uint32(elf.R_ARM_ABS32) | uint32(elfsym)<<8)
 		} else {
 			return false
 		}
 	case objabi.R_PCREL:
-		if r.Siz == 4 {
+		if 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
+		if 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)
@@ -283,7 +283,7 @@
 	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 {
+		if siz == 4 {
 			ctxt.Out.Write32(uint32(elf.R_ARM_GOT_PREL) | uint32(elfsym)<<8)
 		} else {
 			return false
@@ -318,23 +318,24 @@
 	}
 }
 
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool {
 	return false
 }
 
-func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+func pereloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
 	rs := r.Xsym
+	rt := r.Type()
 
-	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)
+	if ldr.SymDynid(rs) < 0 {
+		ldr.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs))
 		return false
 	}
 
 	out.Write32(uint32(sectoff))
-	out.Write32(uint32(rs.Dynid))
+	out.Write32(uint32(ldr.SymDynid(rs)))
 
 	var v uint32
-	switch r.Type {
+	switch rt {
 	default:
 		// unsupported relocation type
 		return false
@@ -526,82 +527,66 @@
 	tramp.AddReloc(r)
 }
 
-func archreloc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
+func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (o int64, needExtReloc bool, ok bool) {
+	rs := r.Sym()
+	rs = ldr.ResolveABIAlias(rs)
 	if target.IsExternal() {
-		switch r.Type {
+		switch r.Type() {
 		case objabi.R_CALLARM:
-			r.Done = false
-
 			// set up addend for eventual relocation via outer symbol.
-			rs := r.Sym
+			rs, off := ld.FoldSubSymbolOffset(ldr, rs)
+			rr.Xadd = int64(signext24(r.Add() & 0xffffff))
+			rr.Xadd *= 4
+			rr.Xadd += off
+			rst := ldr.SymType(rs)
+			if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && rst != sym.SUNDEFEXT && ldr.SymSect(rs) == nil {
+				ldr.Errorf(s, "missing section for %s", ldr.SymName(rs))
+			}
+			rr.Xsym = rs
 
-			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 rr.Xadd/4 > 0x7fffff || rr.Xadd/4 < -0x800000 {
+				ldr.Errorf(s, "direct call too far %d", rr.Xadd/4)
 			}
 
-			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
-
-			// ld64 for arm seems to want the symbol table to contain offset
-			// into the section rather than pseudo virtual address that contains
-			// the section load address.
-			// we need to compensate that by removing the instruction's address
-			// from addend.
-			if target.IsDarwin() {
-				r.Xadd -= ld.Symaddr(s) + int64(r.Off)
-			}
-
-			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 int64(braddoff(int32(0xff000000&uint32(r.Add())), int32(0xffffff&uint32(rr.Xadd/4)))), true, true
 		}
 
-		return -1, false
+		return -1, false, 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(syms.GOT), true
-
+	const isOk = true
+	const noExtReloc = false
+	switch r.Type() {
 	// 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(syms.GOTPLT) < ld.Symaddr(syms.PLT) {
-			ld.Errorf(s, ".got.plt should be placed after .plt section.")
+		if ldr.SymValue(syms.GOTPLT) < ldr.SymValue(syms.PLT) {
+			ldr.Errorf(s, ".got.plt should be placed after .plt section.")
 		}
-		return 0xe28fc600 + (0xff & (int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(syms.PLT)+int64(r.Off))+r.Add)) >> 20)), true
+		return 0xe28fc600 + (0xff & (int64(uint32(ldr.SymValue(rs)-(ldr.SymValue(syms.PLT)+int64(r.Off()))+r.Add())) >> 20)), noExtReloc, isOk
 	case objabi.R_PLT1: // add ip, ip, #0xYY000
-		return 0xe28cca00 + (0xff & (int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(syms.PLT)+int64(r.Off))+r.Add+4)) >> 12)), true
+		return 0xe28cca00 + (0xff & (int64(uint32(ldr.SymValue(rs)-(ldr.SymValue(syms.PLT)+int64(r.Off()))+r.Add()+4)) >> 12)), noExtReloc, isOk
 	case objabi.R_PLT2: // ldr pc, [ip, #0xZZZ]!
-		return 0xe5bcf000 + (0xfff & int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(syms.PLT)+int64(r.Off))+r.Add+8))), true
+		return 0xe5bcf000 + (0xfff & int64(uint32(ldr.SymValue(rs)-(ldr.SymValue(syms.PLT)+int64(r.Off()))+r.Add()+8))), noExtReloc, isOk
 	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
+		t := (ldr.SymValue(rs) + int64(signext24(r.Add()&0xffffff)*4) - (ldr.SymValue(s) + int64(r.Off()))) / 4
 		if t > 0x7fffff || t < -0x800000 {
-			ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
+			ldr.Errorf(s, "direct call too far: %s %x", ldr.SymName(rs), t)
 		}
-		return int64(braddoff(int32(0xff000000&uint32(r.Add)), int32(0xffffff&t))), true
+		return int64(braddoff(int32(0xff000000&uint32(r.Add())), int32(0xffffff&t))), noExtReloc, isOk
 	}
 
-	return val, false
+	return val, false, false
 }
 
-func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
+func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc2, sym.RelocVariant, loader.Sym, int64) int64 {
 	log.Fatalf("unexpected relocation variant")
-	return t
+	return -1
 }
 
-func addpltreloc2(ldr *loader.Loader, plt *loader.SymbolBuilder, got *loader.SymbolBuilder, s loader.Sym, typ objabi.RelocType) {
+func addpltreloc(ldr *loader.Loader, plt *loader.SymbolBuilder, got *loader.SymbolBuilder, s loader.Sym, typ objabi.RelocType) {
 	r, _ := plt.AddRel(typ)
 	r.SetSym(got.Sym())
 	r.SetOff(int32(plt.Size()))
@@ -613,17 +598,17 @@
 	plt.Grow(plt.Size())
 }
 
-func addpltsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
+func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
 	if ldr.SymPlt(s) >= 0 {
 		return
 	}
 
-	ld.Adddynsym2(ldr, target, syms, s)
+	ld.Adddynsym(ldr, target, syms, s)
 
 	if target.IsElf() {
-		plt := ldr.MakeSymbolUpdater(syms.PLT2)
-		got := ldr.MakeSymbolUpdater(syms.GOTPLT2)
-		rel := ldr.MakeSymbolUpdater(syms.RelPLT2)
+		plt := ldr.MakeSymbolUpdater(syms.PLT)
+		got := ldr.MakeSymbolUpdater(syms.GOTPLT)
+		rel := ldr.MakeSymbolUpdater(syms.RelPLT)
 		if plt.Size() == 0 {
 			panic("plt is not set up")
 		}
@@ -639,9 +624,9 @@
 		// .plt entry, this depends on the .got entry
 		ldr.SetPlt(s, int32(plt.Size()))
 
-		addpltreloc2(ldr, plt, got, s, objabi.R_PLT0) // add lr, pc, #0xXX00000
-		addpltreloc2(ldr, plt, got, s, objabi.R_PLT1) // add lr, lr, #0xYY000
-		addpltreloc2(ldr, plt, got, s, objabi.R_PLT2) // ldr pc, [lr, #0xZZZ]!
+		addpltreloc(ldr, plt, got, s, objabi.R_PLT0) // add lr, pc, #0xXX00000
+		addpltreloc(ldr, plt, got, s, objabi.R_PLT1) // add lr, lr, #0xYY000
+		addpltreloc(ldr, plt, got, s, objabi.R_PLT2) // ldr pc, [lr, #0xZZZ]!
 
 		// rel
 		rel.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
@@ -652,12 +637,12 @@
 	}
 }
 
-func addgotsyminternal2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
+func addgotsyminternal(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
 	if ldr.SymGot(s) >= 0 {
 		return
 	}
 
-	got := ldr.MakeSymbolUpdater(syms.GOT2)
+	got := ldr.MakeSymbolUpdater(syms.GOT)
 	ldr.SetGot(s, int32(got.Size()))
 	got.AddAddrPlus(target.Arch, s, 0)
 
@@ -666,133 +651,3 @@
 		ldr.Errorf(s, "addgotsyminternal: unsupported binary format")
 	}
 }
-
-func addgotsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
-	if ldr.SymGot(s) >= 0 {
-		return
-	}
-
-	ld.Adddynsym2(ldr, target, syms, s)
-	got := ldr.MakeSymbolUpdater(syms.GOT2)
-	ldr.SetGot(s, int32(got.Size()))
-	got.AddUint64(target.Arch, 0)
-
-	if target.IsElf() {
-		rel := ldr.MakeSymbolUpdater(syms.Rel2)
-		rel.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
-		rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(ldr.SymDynid(s)), uint32(elf.R_ARM_GLOB_DAT)))
-	} else {
-		ldr.Errorf(s, "addgotsym: unsupported binary format")
-	}
-}
-
-func asmb(ctxt *ld.Link, _ *loader.Loader) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	var wg sync.WaitGroup
-	sect := ld.Segtext.Sections[0]
-	offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-	ld.WriteParallel(&wg, ld.Codeblk, ctxt, offset, sect.Vaddr, sect.Length)
-
-	for _, sect := range ld.Segtext.Sections[1:] {
-		offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, offset, sect.Vaddr, sect.Length)
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrodata.Fileoff, ld.Segrodata.Vaddr, ld.Segrodata.Filelen)
-	}
-
-	if ld.Segrelrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrelrodata.Fileoff, ld.Segrelrodata.Vaddr, ld.Segrelrodata.Filelen)
-	}
-
-	ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segdata.Fileoff, ld.Segdata.Vaddr, ld.Segdata.Filelen)
-
-	ld.WriteParallel(&wg, ld.Dwarfblk, ctxt, ld.Segdwarf.Fileoff, ld.Segdwarf.Vaddr, ld.Segdwarf.Filelen)
-	wg.Wait()
-}
-
-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.Write(ld.Elfstrdat)
-
-				if ctxt.LinkMode == ld.LinkExternal {
-					ld.Elfemitreloc(ctxt)
-				}
-			}
-
-		case objabi.Hplan9:
-			ld.Asmplan9sym(ctxt)
-
-			sym := ctxt.Syms.Lookup("pclntab", 0)
-			if sym != nil {
-				ld.Lcsize = int32(len(sym.P))
-				ctxt.Out.Write(sym.P)
-			}
-
-		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)
-	}
-
-	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/link/internal/arm/obj.go b/src/cmd/link/internal/arm/obj.go
index 47bc053..1a57298 100644
--- a/src/cmd/link/internal/arm/obj.go
+++ b/src/cmd/link/internal/arm/obj.go
@@ -46,16 +46,16 @@
 		Dwarfregsp: dwarfRegSP,
 		Dwarfreglr: dwarfRegLR,
 
-		Adddynrel2:       adddynrel2,
+		Plan9Magic: 0x647,
+
+		Adddynrel:        adddynrel,
 		Archinit:         archinit,
 		Archreloc:        archreloc,
 		Archrelocvariant: archrelocvariant,
 		Trampoline:       trampoline,
-		Asmb:             asmb,
-		Asmb2:            asmb2,
 		Elfreloc1:        elfreloc1,
 		Elfsetupplt:      elfsetupplt,
-		Gentext2:         gentext2,
+		Gentext:          gentext,
 		Machoreloc1:      machoreloc1,
 		PEreloc1:         pereloc1,
 
diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go
index 417e4b1..bb23071 100644
--- a/src/cmd/link/internal/arm64/asm.go
+++ b/src/cmd/link/internal/arm64/asm.go
@@ -37,12 +37,10 @@
 	"cmd/link/internal/loader"
 	"cmd/link/internal/sym"
 	"debug/elf"
-	"fmt"
 	"log"
-	"sync"
 )
 
-func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
+func gentext(ctxt *ld.Link, ldr *loader.Loader) {
 	initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt)
 	if initfunc == nil {
 		return
@@ -62,7 +60,7 @@
 		Off:  0,
 		Size: 8,
 		Type: objabi.R_ADDRARM64,
-		Sym:  ctxt.Moduledata2,
+		Sym:  ctxt.Moduledata,
 	}
 	initfunc.AddReloc(rel)
 
@@ -78,7 +76,7 @@
 	initfunc.AddReloc(rel2)
 }
 
-func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
+func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
 
 	targ := r.Sym()
 	var targType sym.SymKind
@@ -123,9 +121,9 @@
 	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_CALL26),
 		objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_JUMP26):
 		if targType == sym.SDYNIMPORT {
-			addpltsym2(target, ldr, syms, targ)
+			addpltsym(target, ldr, syms, targ)
 			su := ldr.MakeSymbolUpdater(s)
-			su.SetRelocSym(rIdx, syms.PLT2)
+			su.SetRelocSym(rIdx, syms.PLT)
 			su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymPlt(targ)))
 		}
 		if (targType == 0 || targType == sym.SXREF) && !ldr.AttrVisibilityHidden(targ) {
@@ -144,10 +142,10 @@
 
 		// fall back to using GOT
 		// TODO: just needs relocation, no need to put in .dynsym
-		addgotsym2(target, ldr, syms, targ)
+		ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_AARCH64_GLOB_DAT))
 		su := ldr.MakeSymbolUpdater(s)
 		su.SetRelocType(rIdx, objabi.R_ARM64_GOT)
-		su.SetRelocSym(rIdx, syms.GOT2)
+		su.SetRelocSym(rIdx, syms.GOT)
 		su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
 		return true
 
@@ -233,9 +231,9 @@
 			// The code is asking for the address of an external
 			// function. We provide it with the address of the
 			// correspondent GOT symbol.
-			addgotsym2(target, ldr, syms, targ)
+			ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_AARCH64_GLOB_DAT))
 			su := ldr.MakeSymbolUpdater(s)
-			su.SetRelocSym(rIdx, syms.GOT2)
+			su.SetRelocSym(rIdx, syms.GOT)
 			su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
 			return true
 		}
@@ -307,7 +305,7 @@
 			// 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 := ldr.MakeSymbolUpdater(syms.Rela2)
+			rela := ldr.MakeSymbolUpdater(syms.Rela)
 			rela.AddAddrPlus(target.Arch, s, int64(r.Off()))
 			if r.Siz() == 8 {
 				rela.AddUint64(target.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_AARCH64_RELATIVE)))
@@ -325,15 +323,16 @@
 	return false
 }
 
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
+func elfreloc1(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
 	ctxt.Out.Write64(uint64(sectoff))
 
 	elfsym := ld.ElfSymForReloc(ctxt, r.Xsym)
-	switch r.Type {
+	siz := r.Siz()
+	switch r.Type() {
 	default:
 		return false
 	case objabi.R_ADDR, objabi.R_DWARFSECREF:
-		switch r.Siz {
+		switch siz {
 		case 4:
 			ctxt.Out.Write64(uint64(elf.R_AARCH64_ABS32) | uint64(elfsym)<<32)
 		case 8:
@@ -360,7 +359,7 @@
 		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 {
+		if siz != 4 {
 			return false
 		}
 		ctxt.Out.Write64(uint64(elf.R_AARCH64_CALL26) | uint64(elfsym)<<32)
@@ -371,41 +370,43 @@
 	return true
 }
 
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
 	var v uint32
 
 	rs := r.Xsym
+	rt := r.Type()
+	siz := r.Siz()
 
-	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)
+	if ldr.SymType(rs) == sym.SHOSTOBJ || rt == objabi.R_CALLARM64 || rt == objabi.R_ADDRARM64 {
+		if ldr.SymDynid(rs) < 0 {
+			ldr.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs))
 			return false
 		}
 
-		v = uint32(rs.Dynid)
+		v = uint32(ldr.SymDynid(rs))
 		v |= 1 << 27 // external relocation
 	} else {
-		v = uint32(rs.Sect.Extnum)
+		v = uint32(ldr.SymSect(rs).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)
+			ldr.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymSect(rs).Name, ldr.SymType(rs), ldr.SymType(rs))
 			return false
 		}
 	}
 
-	switch r.Type {
+	switch rt {
 	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)
+			ldr.Errorf(s, "ld64 doesn't allow BR26 reloc with non-zero addend: %s+%d", ldr.SymName(rs), r.Xadd)
 		}
 
 		v |= 1 << 24 // pc-relative bit
 		v |= ld.MACHO_ARM64_RELOC_BRANCH26 << 28
 	case objabi.R_ADDRARM64:
-		r.Siz = 4
+		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 {
@@ -422,7 +423,7 @@
 		v |= ld.MACHO_ARM64_RELOC_PAGE21 << 28
 	}
 
-	switch r.Siz {
+	switch siz {
 	default:
 		return false
 	case 1:
@@ -440,56 +441,26 @@
 	return true
 }
 
-func archreloc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
+func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (int64, bool, bool) {
+	const extRelocNeeded = true
+	const extRelocNotNeeded = false
+	const isOk = true
+
+	rs := ldr.ResolveABIAlias(r.Sym())
+
 	if target.IsExternal() {
-		switch r.Type {
+		switch r.Type() {
 		default:
-			return val, false
-		case objabi.R_ARM64_GOTPCREL:
-			var o1, o2 uint32
-			if target.IsBigEndian() {
-				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 && target.IsDynlinkingGo() {
-				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 target.IsBigEndian() {
-				val = int64(o1)<<32 | int64(o2)
-			} else {
-				val = int64(o2)<<32 | int64(o1)
-			}
-			fallthrough
-		case objabi.R_ADDRARM64:
-			r.Done = false
-
+		case objabi.R_ARM64_GOTPCREL,
+			objabi.R_ADDRARM64:
 			// 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
+			rs, off := ld.FoldSubSymbolOffset(ldr, rs)
+			rr.Xadd = r.Add() + off
+			rst := ldr.SymType(rs)
+			if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && ldr.SymSect(rs) == nil {
+				ldr.Errorf(s, "missing section for %s", ldr.SymName(rs))
 			}
-
-			if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
-				ld.Errorf(s, "missing section for %s", rs.Name)
-			}
-			r.Xsym = rs
+			rr.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
@@ -511,9 +482,9 @@
 				// 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
+				o0 |= (uint32((rr.Xadd>>12)&3) << 29) | (uint32((rr.Xadd>>12>>2)&0x7ffff) << 5)
+				o1 |= uint32(rr.Xadd&0xfff) << 10
+				rr.Xadd = 0
 
 				// when laid out, the instruction order must always be o1, o2.
 				if target.IsBigEndian() {
@@ -523,28 +494,21 @@
 				}
 			}
 
-			return val, true
+			return val, extRelocNeeded, isOk
 		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
+			rr.Xsym = rs
+			rr.Xadd = r.Add()
+			return val, extRelocNeeded, isOk
 		}
 	}
 
-	switch r.Type {
-	case objabi.R_CONST:
-		return r.Add, true
-
-	case objabi.R_GOTOFF:
-		return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(syms.GOT), true
-
+	switch r.Type() {
 	case objabi.R_ADDRARM64:
-		t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
+		t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff)
 		if t >= 1<<32 || t < -1<<32 {
-			ld.Errorf(s, "program too large, address relocation distance = %d", t)
+			ldr.Errorf(s, "program too large, address relocation distance = %d", t)
 		}
 
 		var o0, o1 uint32
@@ -562,37 +526,36 @@
 
 		// when laid out, the instruction order must always be o1, o2.
 		if target.IsBigEndian() {
-			return int64(o0)<<32 | int64(o1), true
+			return int64(o0)<<32 | int64(o1), extRelocNotNeeded, true
 		}
-		return int64(o1)<<32 | int64(o0), true
+		return int64(o1)<<32 | int64(o0), extRelocNotNeeded, true
 
 	case objabi.R_ARM64_TLS_LE:
-		r.Done = false
 		if target.IsDarwin() {
-			ld.Errorf(s, "TLS reloc on unsupported OS %v", target.HeadType)
+			ldr.Errorf(s, "TLS reloc on unsupported OS %v", target.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*target.Arch.PtrSize)
+		v := ldr.SymValue(rs) + int64(2*target.Arch.PtrSize)
 		if v < 0 || v >= 32678 {
-			ld.Errorf(s, "TLS offset out of range %d", v)
+			ldr.Errorf(s, "TLS offset out of range %d", v)
 		}
-		return val | (v << 5), true
+		return val | (v << 5), extRelocNeeded, true
 
 	case objabi.R_ARM64_TLS_IE:
 		if target.IsPIE() && target.IsElf() {
 			// We are linking the final executable, so we
 			// can optimize any TLS IE relocation to LE.
-			r.Done = false
+
 			if !target.IsLinux() {
-				ld.Errorf(s, "TLS reloc on unsupported OS %v", target.HeadType)
+				ldr.Errorf(s, "TLS reloc on unsupported OS %v", target.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*target.Arch.PtrSize) + r.Add
+			v := ldr.SymAddr(rs) + int64(2*target.Arch.PtrSize) + r.Add()
 			if v < 0 || v >= 32678 {
-				ld.Errorf(s, "TLS offset out of range %d", v)
+				ldr.Errorf(s, "TLS offset out of range %d", v)
 			}
 
 			var o0, o1 uint32
@@ -610,110 +573,112 @@
 			// 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)
+				ldr.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 target.IsBigEndian() {
-				return int64(o0)<<32 | int64(o1), true
+				return int64(o0)<<32 | int64(o1), extRelocNotNeeded, isOk
 			}
-			return int64(o1)<<32 | int64(o0), true
+			return int64(o1)<<32 | int64(o0), extRelocNotNeeded, isOk
 		} else {
-			log.Fatalf("cannot handle R_ARM64_TLS_IE (sym %s) when linking internally", s.Name)
+			log.Fatalf("cannot handle R_ARM64_TLS_IE (sym %s) when linking internally", ldr.SymName(s))
 		}
 
 	case objabi.R_CALLARM64:
 		var t int64
-		if r.Sym.Type == sym.SDYNIMPORT {
-			t = (ld.Symaddr(syms.PLT) + r.Add) - (s.Value + int64(r.Off))
+		if ldr.SymType(rs) == sym.SDYNIMPORT {
+			t = (ldr.SymAddr(syms.PLT) + r.Add()) - (ldr.SymValue(s) + int64(r.Off()))
 		} else {
-			t = (ld.Symaddr(r.Sym) + r.Add) - (s.Value + int64(r.Off))
+			t = (ldr.SymAddr(rs) + r.Add()) - (ldr.SymValue(s) + int64(r.Off()))
 		}
 		if t >= 1<<27 || t < -1<<27 {
-			ld.Errorf(s, "program too large, call relocation distance = %d", t)
+			ldr.Errorf(s, "program too large, call relocation distance = %d", t)
 		}
-		return val | ((t >> 2) & 0x03ffffff), true
+		return val | ((t >> 2) & 0x03ffffff), extRelocNotNeeded, true
 
 	case objabi.R_ARM64_GOT:
-		if s.P[r.Off+3]&0x9f == 0x90 {
+		sData := ldr.Data(s)
+		if sData[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)
+			t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff)
 			if t >= 1<<32 || t < -1<<32 {
-				ld.Errorf(s, "program too large, address relocation distance = %d", t)
+				ldr.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 {
+			return val | int64(o0), extRelocNotNeeded, isOk
+		} else if sData[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)
+			t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff)
 			if t&7 != 0 {
-				ld.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_LD64_GOT_LO12_NC", t)
+				ldr.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
+			return val | int64(uint64(o1)), extRelocNotNeeded, isOk
 		} else {
-			ld.Errorf(s, "unsupported instruction for %v R_GOTARM64", s.P[r.Off:r.Off+4])
+			ldr.Errorf(s, "unsupported instruction for %v R_GOTARM64", sData[r.Off():r.Off()+4])
 		}
 
 	case objabi.R_ARM64_PCREL:
-		if s.P[r.Off+3]&0x9f == 0x90 {
+		sData := ldr.Data(s)
+		if sData[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)
+			t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff)
 			if t >= 1<<32 || t < -1<<32 {
-				ld.Errorf(s, "program too large, address relocation distance = %d", t)
+				ldr.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 {
+			return val | int64(o0), extRelocNotNeeded, isOk
+		} else if sData[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)
+			t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff)
 			o1 := uint32(t&0xfff) << 10
-			return val | int64(o1), true
+			return val | int64(o1), extRelocNotNeeded, isOk
 		} else {
-			ld.Errorf(s, "unsupported instruction for %v R_PCRELARM64", s.P[r.Off:r.Off+4])
+			ldr.Errorf(s, "unsupported instruction for %v R_PCRELARM64", sData[r.Off():r.Off()+4])
 		}
 
 	case objabi.R_ARM64_LDST8:
-		t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
+		t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff)
 		o0 := uint32(t&0xfff) << 10
-		return val | int64(o0), true
+		return val | int64(o0), extRelocNotNeeded, true
 
 	case objabi.R_ARM64_LDST32:
-		t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
+		t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff)
 		if t&3 != 0 {
-			ld.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_LDST32_ABS_LO12_NC", t)
+			ldr.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
+		return val | int64(o0), extRelocNotNeeded, true
 
 	case objabi.R_ARM64_LDST64:
-		t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
+		t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff)
 		if t&7 != 0 {
-			ld.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_LDST64_ABS_LO12_NC", t)
+			ldr.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
+		return val | int64(o0), extRelocNotNeeded, true
 
 	case objabi.R_ARM64_LDST128:
-		t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
+		t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff)
 		if t&15 != 0 {
-			ld.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_LDST128_ABS_LO12_NC", t)
+			ldr.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 | int64(o0), extRelocNotNeeded, true
 	}
 
-	return val, false
+	return val, false, false
 }
 
-func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
+func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc2, sym.RelocVariant, loader.Sym, int64) int64 {
 	log.Fatalf("unexpected relocation variant")
 	return -1
 }
@@ -757,17 +722,17 @@
 	}
 }
 
-func addpltsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
+func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
 	if ldr.SymPlt(s) >= 0 {
 		return
 	}
 
-	ld.Adddynsym2(ldr, target, syms, s)
+	ld.Adddynsym(ldr, target, syms, s)
 
 	if target.IsElf() {
-		plt := ldr.MakeSymbolUpdater(syms.PLT2)
-		gotplt := ldr.MakeSymbolUpdater(syms.GOTPLT2)
-		rela := ldr.MakeSymbolUpdater(syms.RelaPLT2)
+		plt := ldr.MakeSymbolUpdater(syms.PLT)
+		gotplt := ldr.MakeSymbolUpdater(syms.GOTPLT)
+		rela := ldr.MakeSymbolUpdater(syms.RelaPLT)
 		if plt.Size() == 0 {
 			panic("plt is not set up")
 		}
@@ -809,140 +774,3 @@
 		ldr.Errorf(s, "addpltsym: unsupported binary format")
 	}
 }
-
-func addgotsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
-	if ldr.SymGot(s) >= 0 {
-		return
-	}
-
-	ld.Adddynsym2(ldr, target, syms, s)
-	got := ldr.MakeSymbolUpdater(syms.GOT2)
-	ldr.SetGot(s, int32(got.Size()))
-	got.AddUint64(target.Arch, 0)
-
-	if target.IsElf() {
-		rela := ldr.MakeSymbolUpdater(syms.Rela2)
-		rela.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
-		rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(ldr.SymDynid(s)), uint32(elf.R_AARCH64_GLOB_DAT)))
-		rela.AddUint64(target.Arch, 0)
-	} else {
-		ldr.Errorf(s, "addgotsym: unsupported binary format")
-	}
-}
-
-func asmb(ctxt *ld.Link, _ *loader.Loader) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	var wg sync.WaitGroup
-	sect := ld.Segtext.Sections[0]
-	offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-	ld.WriteParallel(&wg, ld.Codeblk, ctxt, offset, sect.Vaddr, sect.Length)
-
-	for _, sect := range ld.Segtext.Sections[1:] {
-		offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, offset, sect.Vaddr, sect.Length)
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrodata.Fileoff, ld.Segrodata.Vaddr, ld.Segrodata.Filelen)
-	}
-
-	if ld.Segrelrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrelrodata.Fileoff, ld.Segrelrodata.Vaddr, ld.Segrelrodata.Filelen)
-	}
-
-	ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segdata.Fileoff, ld.Segdata.Vaddr, ld.Segdata.Filelen)
-
-	ld.WriteParallel(&wg, ld.Dwarfblk, ctxt, ld.Segdwarf.Fileoff, ld.Segdwarf.Vaddr, ld.Segdwarf.Filelen)
-	wg.Wait()
-}
-
-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.Write(ld.Elfstrdat)
-
-				if ctxt.LinkMode == ld.LinkExternal {
-					ld.Elfemitreloc(ctxt)
-				}
-			}
-
-		case objabi.Hplan9:
-			ld.Asmplan9sym(ctxt)
-
-			sym := ctxt.Syms.Lookup("pclntab", 0)
-			if sym != nil {
-				ld.Lcsize = int32(len(sym.P))
-				ctxt.Out.Write(sym.P)
-			}
-
-		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)
-	}
-
-	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/link/internal/arm64/obj.go b/src/cmd/link/internal/arm64/obj.go
index 20426c5..8eeba0d 100644
--- a/src/cmd/link/internal/arm64/obj.go
+++ b/src/cmd/link/internal/arm64/obj.go
@@ -46,15 +46,13 @@
 		Dwarfregsp: dwarfRegSP,
 		Dwarfreglr: dwarfRegLR,
 
-		Adddynrel2:       adddynrel2,
+		Adddynrel:        adddynrel,
 		Archinit:         archinit,
 		Archreloc:        archreloc,
 		Archrelocvariant: archrelocvariant,
-		Asmb:             asmb,
-		Asmb2:            asmb2,
 		Elfreloc1:        elfreloc1,
 		Elfsetupplt:      elfsetupplt,
-		Gentext2:         gentext2,
+		Gentext:          gentext,
 		Machoreloc1:      machoreloc1,
 
 		Androiddynld: "/system/bin/linker64",
diff --git a/src/cmd/link/internal/ld/asmb.go b/src/cmd/link/internal/ld/asmb.go
new file mode 100644
index 0000000..a9987ba
--- /dev/null
+++ b/src/cmd/link/internal/ld/asmb.go
@@ -0,0 +1,161 @@
+// Copyright 2020 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/link/internal/loader"
+	"fmt"
+	"sync"
+)
+
+// Assembling the binary is broken into two steps:
+//  - writing out the code/data/dwarf Segments
+//  - writing out the architecture specific pieces.
+// This function handles the first part.
+func asmb(ctxt *Link, ldr *loader.Loader) {
+	// TODO(jfaller): delete me.
+	if thearch.Asmb != nil {
+		thearch.Asmb(ctxt, ldr)
+		return
+	}
+
+	if ctxt.IsELF {
+		Asmbelfsetup()
+	}
+
+	var wg sync.WaitGroup
+	sect := Segtext.Sections[0]
+	offset := sect.Vaddr - Segtext.Vaddr + Segtext.Fileoff
+	f := func(ctxt *Link, out *OutBuf, start, length int64) {
+		pad := thearch.CodePad
+		if pad == nil {
+			pad = zeros[:]
+		}
+		CodeblkPad(ctxt, out, start, length, pad)
+	}
+
+	if !thearch.WriteTextBlocks {
+		writeParallel(&wg, f, ctxt, offset, sect.Vaddr, sect.Length)
+		for _, sect := range Segtext.Sections[1:] {
+			offset := sect.Vaddr - Segtext.Vaddr + Segtext.Fileoff
+			writeParallel(&wg, Datblk, ctxt, offset, sect.Vaddr, sect.Length)
+		}
+	} else {
+		// TODO why can't we handle all sections this way?
+		for _, sect := range Segtext.Sections {
+			offset := sect.Vaddr - Segtext.Vaddr + Segtext.Fileoff
+			// Handle additional text sections with Codeblk
+			if sect.Name == ".text" {
+				writeParallel(&wg, f, ctxt, offset, sect.Vaddr, sect.Length)
+			} else {
+				writeParallel(&wg, Datblk, ctxt, offset, sect.Vaddr, sect.Length)
+			}
+		}
+	}
+
+	if Segrodata.Filelen > 0 {
+		writeParallel(&wg, Datblk, ctxt, Segrodata.Fileoff, Segrodata.Vaddr, Segrodata.Filelen)
+	}
+
+	if Segrelrodata.Filelen > 0 {
+		writeParallel(&wg, Datblk, ctxt, Segrelrodata.Fileoff, Segrelrodata.Vaddr, Segrelrodata.Filelen)
+	}
+
+	writeParallel(&wg, Datblk, ctxt, Segdata.Fileoff, Segdata.Vaddr, Segdata.Filelen)
+
+	writeParallel(&wg, dwarfblk, ctxt, Segdwarf.Fileoff, Segdwarf.Vaddr, Segdwarf.Filelen)
+
+	wg.Wait()
+}
+
+// Assembling the binary is broken into two steps:
+//  - writing out the code/data/dwarf Segments
+//  - writing out the architecture specific pieces.
+// This function handles the second part.
+func asmb2(ctxt *Link) {
+	if thearch.Asmb2 != nil {
+		thearch.Asmb2(ctxt, ctxt.loader)
+		return
+	}
+
+	symSize = 0
+	spSize = 0
+	lcSize = 0
+
+	switch ctxt.HeadType {
+	default:
+		panic("unknown platform")
+
+	// Macho
+	case objabi.Hdarwin:
+		asmbMacho(ctxt)
+
+	// Plan9
+	case objabi.Hplan9:
+		asmbPlan9(ctxt)
+
+	// PE
+	case objabi.Hwindows:
+		asmbPe(ctxt)
+
+	// Xcoff
+	case objabi.Haix:
+		asmbXcoff(ctxt)
+
+	// Elf
+	case objabi.Hdragonfly,
+		objabi.Hfreebsd,
+		objabi.Hlinux,
+		objabi.Hnetbsd,
+		objabi.Hopenbsd,
+		objabi.Hsolaris:
+		asmbElf(ctxt)
+	}
+
+	if *FlagC {
+		fmt.Printf("textsize=%d\n", Segtext.Filelen)
+		fmt.Printf("datsize=%d\n", Segdata.Filelen)
+		fmt.Printf("bsssize=%d\n", Segdata.Length-Segdata.Filelen)
+		fmt.Printf("symsize=%d\n", symSize)
+		fmt.Printf("lcsize=%d\n", lcSize)
+		fmt.Printf("total=%d\n", Segtext.Filelen+Segdata.Length+uint64(symSize)+uint64(lcSize))
+	}
+}
+
+// writePlan9Header writes out the plan9 header at the present position in the OutBuf.
+func writePlan9Header(buf *OutBuf, magic uint32, entry int64, is64Bit bool) {
+	if is64Bit {
+		magic |= 0x00008000
+	}
+	buf.Write32b(magic)
+	buf.Write32b(uint32(Segtext.Filelen))
+	buf.Write32b(uint32(Segdata.Filelen))
+	buf.Write32b(uint32(Segdata.Length - Segdata.Filelen))
+	buf.Write32b(uint32(symSize))
+	if is64Bit {
+		buf.Write32b(uint32(entry &^ 0x80000000))
+	} else {
+		buf.Write32b(uint32(entry))
+	}
+	buf.Write32b(uint32(spSize))
+	buf.Write32b(uint32(lcSize))
+	// amd64 includes the entry at the beginning of the symbol table.
+	if is64Bit {
+		buf.Write64b(uint64(entry))
+	}
+}
+
+// asmbPlan9 assembles a plan 9 binary.
+func asmbPlan9(ctxt *Link) {
+	if !*FlagS {
+		*FlagS = true
+		symo := int64(Segdata.Fileoff + Segdata.Filelen)
+		ctxt.Out.SeekSet(symo)
+		asmbPlan9Sym(ctxt)
+	}
+	ctxt.Out.SeekSet(0)
+	writePlan9Header(ctxt.Out, thearch.Plan9Magic, Entryvalue(ctxt), thearch.Plan9_64Bit)
+}
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index d3f308c..8fec08b 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -120,16 +120,15 @@
 
 }
 
-// foldSubSymbolOffset computes the offset of symbol s to its top-level outer
+// FoldSubSymbolOffset computes the offset of symbol s to its top-level outer
 // symbol. Returns the top-level symbol and the offset.
 // This is used in generating external relocations.
-func foldSubSymbolOffset(ldr *loader.Loader, s loader.Sym) (loader.Sym, int64) {
+func FoldSubSymbolOffset(ldr *loader.Loader, s loader.Sym) (loader.Sym, int64) {
 	outer := ldr.OuterSym(s)
 	off := int64(0)
-	for outer != 0 {
+	if outer != 0 {
 		off += ldr.SymValue(s) - ldr.SymValue(outer)
 		s = outer
-		outer = ldr.OuterSym(s)
 	}
 	return s, off
 }
@@ -179,6 +178,9 @@
 			st.err.Errorf(s, "invalid relocation %s: %d+%d not in [%d,%d)", rname, off, siz, 0, len(P))
 			continue
 		}
+		if siz == 0 { // informational relocation - no work to do
+			continue
+		}
 
 		var rst sym.SymKind
 		if rs != 0 {
@@ -206,9 +208,6 @@
 		if rt >= objabi.ElfRelocOffset {
 			continue
 		}
-		if 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
@@ -227,18 +226,21 @@
 			rr.Idx = ri
 		}
 
+		var rv sym.RelocVariant
+		if target.IsPPC64() || target.IsS390X() {
+			rv = ldr.RelocVariant(s, ri)
+		}
+
 		// TODO(mundaym): remove this special case - see issue 14218.
-		//if target.IsS390X() {
-		//	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
-		//	}
-		//}
+		if target.IsS390X() {
+			switch rt {
+			case objabi.R_PCRELDBL:
+				rt = objabi.R_PCREL
+				rv = sym.RV_390_DBL
+			case objabi.R_CALL:
+				rv = sym.RV_390_DBL
+			}
+		}
 
 		var o int64
 		switch rt {
@@ -257,14 +259,14 @@
 			}
 			var rp *loader.ExtReloc
 			if target.IsExternal() {
-				// Don't pass &rr directly to Archreloc2, which will escape rr
+				// Don't pass &rr directly to Archreloc, which will escape rr
 				// even if this case is not taken. Instead, as Archreloc2 will
 				// likely return true, we speculatively add rr to extRelocs
-				// and use that space to pass to Archreloc2.
+				// and use that space to pass to Archreloc.
 				extRelocs = append(extRelocs, rr)
 				rp = &extRelocs[len(extRelocs)-1]
 			}
-			out, needExtReloc1, ok := thearch.Archreloc2(target, ldr, syms, r, rp, s, o)
+			out, needExtReloc1, ok := thearch.Archreloc(target, ldr, syms, r, rp, s, o)
 			if target.IsExternal() && !needExtReloc1 {
 				// Speculation failed. Undo the append.
 				extRelocs = extRelocs[:len(extRelocs)-1]
@@ -280,7 +282,7 @@
 				needExtReloc = true
 				rr.Xsym = rs
 				if rr.Xsym == 0 {
-					rr.Xsym = syms.Tlsg2
+					rr.Xsym = syms.Tlsg
 				}
 				rr.Xadd = r.Add()
 				o = 0
@@ -311,7 +313,7 @@
 				needExtReloc = true
 				rr.Xsym = rs
 				if rr.Xsym == 0 {
-					rr.Xsym = syms.Tlsg2
+					rr.Xsym = syms.Tlsg
 				}
 				rr.Xadd = r.Add()
 				o = 0
@@ -332,12 +334,12 @@
 				log.Fatalf("cannot handle R_TLS_IE (sym %s) when linking internally", ldr.SymName(s))
 			}
 		case objabi.R_ADDR:
-			if target.IsExternal() && rst != sym.SCONST {
+			if target.IsExternal() {
 				needExtReloc = true
 
 				// set up addend for eventual relocation via outer symbol.
 				rs := rs
-				rs, off := foldSubSymbolOffset(ldr, rs)
+				rs, off := FoldSubSymbolOffset(ldr, rs)
 				rr.Xadd = r.Add() + off
 				rst := ldr.SymType(rs)
 				if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && rst != sym.SUNDEFEXT && ldr.SymSect(rs) == nil {
@@ -357,7 +359,7 @@
 				} else if target.IsWindows() {
 					// nothing to do
 				} else if target.IsAIX() {
-					o = ldr.SymValue(rs) + r.Add()
+					o = ldr.SymValue(rs) + rr.Xadd
 				} else {
 					st.err.Errorf(s, "unhandled pcrel relocation to %s on %v", ldr.SymName(rs), target.HeadType)
 				}
@@ -376,8 +378,7 @@
 				// symbol which isn't in .data. However, as .text has the
 				// same address once loaded, this is possible.
 				if ldr.SymSect(s).Seg == &Segdata {
-					panic("not implemented")
-					//Xcoffadddynrel(target, ldr, err, s, &r) // XXX
+					Xcoffadddynrel(target, ldr, syms, s, r, ri)
 				}
 			}
 
@@ -409,7 +410,7 @@
 					needExtReloc = false
 				}
 
-				rr.Xsym = loader.Sym(ldr.SymSect(rs).Sym2)
+				rr.Xsym = loader.Sym(ldr.SymSect(rs).Sym)
 				rr.Xadd = r.Add() + ldr.SymValue(rs) - int64(ldr.SymSect(rs).Vaddr)
 
 				o = rr.Xadd
@@ -436,11 +437,11 @@
 		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 = ldr.SymValue(rs) + r.Add() - ldr.SymValue(loader.Sym(ldr.SymUnit(rs).Textp2[0]))
+			o = ldr.SymValue(rs) + r.Add() - ldr.SymValue(loader.Sym(ldr.SymUnit(rs).Textp[0]))
 
 		// r.Sym() can be 0 when CALL $(constant) is transformed from absolute PC to relative PC call.
 		case objabi.R_GOTPCREL:
-			if target.IsDynlinkingGo() && target.IsDarwin() && rs != 0 && rst != sym.SCONST {
+			if target.IsDynlinkingGo() && target.IsDarwin() && rs != 0 {
 				needExtReloc = true
 				rr.Xadd = r.Add()
 				rr.Xadd -= int64(siz) // relative to address after the relocated chunk
@@ -463,12 +464,12 @@
 				o = 0
 				break
 			}
-			if target.IsExternal() && rs != 0 && rst != sym.SCONST && (ldr.SymSect(rs) != ldr.SymSect(s) || rt == objabi.R_GOTPCREL) {
+			if target.IsExternal() && rs != 0 && (ldr.SymSect(rs) != ldr.SymSect(s) || rt == objabi.R_GOTPCREL) {
 				needExtReloc = true
 
 				// set up addend for eventual relocation via outer symbol.
 				rs := rs
-				rs, off := foldSubSymbolOffset(ldr, rs)
+				rs, off := FoldSubSymbolOffset(ldr, rs)
 				rr.Xadd = r.Add() + off
 				rr.Xadd -= int64(siz) // relative to address after the relocated chunk
 				rst := ldr.SymType(rs)
@@ -528,10 +529,7 @@
 			needExtReloc = true
 			rr.Xsym = rs
 			rr.Xadd = r.Add()
-
-			// This isn't a real relocation so it must not update
-			// its offset value.
-			continue
+			goto addExtReloc
 
 		case objabi.R_DWARFFILEREF:
 			// We don't renumber files in dwarf.go:writelines anymore.
@@ -541,15 +539,14 @@
 			o = r.Add()
 
 		case objabi.R_GOTOFF:
-			o = ldr.SymValue(rs) + r.Add() - ldr.SymValue(syms.GOT2)
+			o = ldr.SymValue(rs) + r.Add() - ldr.SymValue(syms.GOT)
 		}
 
-		//if target.IsPPC64() || target.IsS390X() {
-		//	r.InitExt()
-		//	if r.Variant != sym.RV_NONE {
-		//		o = thearch.Archrelocvariant(ldr, target, syms, &r, s, o)
-		//	}
-		//}
+		if target.IsPPC64() || target.IsS390X() {
+			if rv != sym.RV_NONE {
+				o = thearch.Archrelocvariant(target, ldr, r, rv, s, o)
+			}
+		}
 
 		switch siz {
 		default:
@@ -576,6 +573,7 @@
 			target.Arch.ByteOrder.PutUint64(P[off:], uint64(o))
 		}
 
+	addExtReloc:
 		if needExtReloc {
 			extRelocs = append(extRelocs, rr)
 		}
@@ -652,7 +650,7 @@
 	go func() {
 		if !ctxt.IsWasm() { // On Wasm, text relocations are applied in Asmb2.
 			st := ctxt.makeRelocSymState()
-			for _, s := range ctxt.Textp2 {
+			for _, s := range ctxt.Textp {
 				st.relocsym(s, ldr.OutData(s))
 			}
 		}
@@ -660,14 +658,14 @@
 	}()
 	go func() {
 		st := ctxt.makeRelocSymState()
-		for _, s := range ctxt.datap2 {
+		for _, s := range ctxt.datap {
 			st.relocsym(s, ldr.OutData(s))
 		}
 		wg.Done()
 	}()
 	go func() {
 		st := ctxt.makeRelocSymState()
-		for _, si := range dwarfp2 {
+		for _, si := range dwarfp {
 			for _, s := range si.syms {
 				st.relocsym(s, ldr.OutData(s))
 			}
@@ -746,14 +744,14 @@
 	relu := ctxt.loader.MakeSymbolUpdater(rel)
 	relu.SetType(sym.STEXT)
 
-	for _, s := range ctxt.Textp2 {
+	for _, s := range ctxt.Textp {
 		windynrelocsym(ctxt, relu, s)
 	}
 
-	ctxt.Textp2 = append(ctxt.Textp2, rel)
+	ctxt.Textp = append(ctxt.Textp, rel)
 }
 
-func dynrelocsym2(ctxt *Link, s loader.Sym) {
+func dynrelocsym(ctxt *Link, s loader.Sym) {
 	target := &ctxt.Target
 	ldr := ctxt.loader
 	syms := &ctxt.ArchSyms
@@ -764,7 +762,7 @@
 			// 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.Adddynrel2(target, ldr, syms, s, r, ri)
+			thearch.Adddynrel(target, ldr, syms, s, r, ri)
 			continue
 		}
 
@@ -773,14 +771,14 @@
 			if rSym != 0 && !ldr.AttrReachable(rSym) {
 				ctxt.Errorf(s, "dynamic relocation to unreachable symbol %s", ldr.SymName(rSym))
 			}
-			if !thearch.Adddynrel2(target, ldr, syms, s, r, ri) {
+			if !thearch.Adddynrel(target, ldr, syms, s, r, ri) {
 				ctxt.Errorf(s, "unsupported dynamic relocation for symbol %s (type=%d (%s) stype=%d (%s))", ldr.SymName(rSym), r.Type(), sym.RelocName(ctxt.Arch, r.Type()), ldr.SymType(rSym), ldr.SymType(rSym))
 			}
 		}
 	}
 }
 
-func (state *dodataState) dynreloc2(ctxt *Link) {
+func (state *dodataState) dynreloc(ctxt *Link) {
 	if ctxt.HeadType == objabi.Hwindows {
 		return
 	}
@@ -790,25 +788,21 @@
 		return
 	}
 
-	for _, s := range ctxt.Textp2 {
-		dynrelocsym2(ctxt, s)
+	for _, s := range ctxt.Textp {
+		dynrelocsym(ctxt, s)
 	}
-	for _, syms := range state.data2 {
+	for _, syms := range state.data {
 		for _, s := range syms {
-			dynrelocsym2(ctxt, s)
+			dynrelocsym(ctxt, s)
 		}
 	}
 	if ctxt.IsELF {
-		elfdynhash2(ctxt)
+		elfdynhash(ctxt)
 	}
 }
 
-func Codeblk(ctxt *Link, out *OutBuf, addr int64, size int64) {
-	CodeblkPad(ctxt, out, addr, size, zeros[:])
-}
-
 func CodeblkPad(ctxt *Link, out *OutBuf, addr int64, size int64, pad []byte) {
-	writeBlocks(out, ctxt.outSem, ctxt.loader, ctxt.Textp2, addr, size, pad)
+	writeBlocks(out, ctxt.outSem, ctxt.loader, ctxt.Textp, addr, size, pad)
 }
 
 const blockSize = 1 << 20 // 1MB chunks written at a time.
@@ -953,8 +947,8 @@
 
 type writeFn func(*Link, *OutBuf, int64, int64)
 
-// WriteParallel handles scheduling parallel execution of data write functions.
-func WriteParallel(wg *sync.WaitGroup, fn writeFn, ctxt *Link, seek, vaddr, length uint64) {
+// writeParallel handles scheduling parallel execution of data write functions.
+func writeParallel(wg *sync.WaitGroup, fn writeFn, ctxt *Link, seek, vaddr, length uint64) {
 	if out, err := ctxt.Out.View(seek); err != nil {
 		ctxt.Out.SeekSet(int64(seek))
 		fn(ctxt, ctxt.Out, int64(vaddr), int64(length))
@@ -980,10 +974,10 @@
 }
 
 func writeDatblkToOutBuf(ctxt *Link, out *OutBuf, addr int64, size int64) {
-	writeBlocks(out, ctxt.outSem, ctxt.loader, ctxt.datap2, addr, size, zeros[:])
+	writeBlocks(out, ctxt.outSem, ctxt.loader, ctxt.datap, addr, size, zeros[:])
 }
 
-func Dwarfblk(ctxt *Link, out *OutBuf, addr int64, size int64) {
+func dwarfblk(ctxt *Link, out *OutBuf, addr int64, size int64) {
 	// Concatenate the section symbol lists into a single list to pass
 	// to writeBlocks.
 	//
@@ -991,12 +985,12 @@
 	// section, but this would run the risk of undoing any file offset
 	// adjustments made during layout.
 	n := 0
-	for i := range dwarfp2 {
-		n += len(dwarfp2[i].syms)
+	for i := range dwarfp {
+		n += len(dwarfp[i].syms)
 	}
 	syms := make([]loader.Sym, 0, n)
-	for i := range dwarfp2 {
-		syms = append(syms, dwarfp2[i].syms...)
+	for i := range dwarfp {
+		syms = append(syms, dwarfp[i].syms...)
 	}
 	writeBlocks(out, ctxt.outSem, ctxt.loader, syms, addr, size, zeros[:])
 }
@@ -1094,9 +1088,8 @@
 }
 
 // symalign returns the required alignment for the given symbol s.
-func (state *dodataState) symalign2(s loader.Sym) int32 {
+func symalign(ldr *loader.Loader, s loader.Sym) int32 {
 	min := int32(thearch.Minalign)
-	ldr := state.ctxt.loader
 	align := ldr.SymAlign(s)
 	if align >= min {
 		return align
@@ -1119,19 +1112,19 @@
 	return align
 }
 
-func aligndatsize2(state *dodataState, datsize int64, s loader.Sym) int64 {
-	return Rnd(datsize, int64(state.symalign2(s)))
+func aligndatsize(state *dodataState, datsize int64, s loader.Sym) int64 {
+	return Rnd(datsize, int64(symalign(state.ctxt.loader, s)))
 }
 
 const debugGCProg = false
 
-type GCProg2 struct {
+type GCProg struct {
 	ctxt *Link
 	sym  *loader.SymbolBuilder
 	w    gcprog.Writer
 }
 
-func (p *GCProg2) Init(ctxt *Link, name string) {
+func (p *GCProg) Init(ctxt *Link, name string) {
 	p.ctxt = ctxt
 	symIdx := ctxt.loader.LookupOrCreateSym(name, 0)
 	p.sym = ctxt.loader.MakeSymbolUpdater(symIdx)
@@ -1142,13 +1135,13 @@
 	}
 }
 
-func (p *GCProg2) writeByte() func(x byte) {
+func (p *GCProg) writeByte() func(x byte) {
 	return func(x byte) {
 		p.sym.AddUint8(x)
 	}
 }
 
-func (p *GCProg2) End(size int64) {
+func (p *GCProg) End(size int64) {
 	p.w.ZeroUntil(size / int64(p.ctxt.Arch.PtrSize))
 	p.w.End()
 	if debugGCProg {
@@ -1156,7 +1149,7 @@
 	}
 }
 
-func (p *GCProg2) AddSym(s loader.Sym) {
+func (p *GCProg) AddSym(s loader.Sym) {
 	ldr := p.ctxt.loader
 	typ := ldr.SymGoType(s)
 
@@ -1211,7 +1204,7 @@
 }
 
 // fixZeroSizedSymbols gives a few special symbols with zero size some space.
-func fixZeroSizedSymbols2(ctxt *Link) {
+func fixZeroSizedSymbols(ctxt *Link) {
 	// 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
@@ -1280,7 +1273,7 @@
 }
 
 // makeRelroForSharedLib creates a section of readonly data if necessary.
-func (state *dodataState) makeRelroForSharedLib2(target *Link) {
+func (state *dodataState) makeRelroForSharedLib(target *Link) {
 	if !target.UseRelro() {
 		return
 	}
@@ -1293,9 +1286,9 @@
 		symnrelro := sym.RelROMap[symnro]
 
 		ro := []loader.Sym{}
-		relro := state.data2[symnrelro]
+		relro := state.data[symnrelro]
 
-		for _, s := range state.data2[symnro] {
+		for _, s := range state.data[symnro] {
 			relocs := ldr.Relocs(s)
 			isRelro := relocs.Count() > 0
 			switch state.symType(s) {
@@ -1337,8 +1330,8 @@
 			}
 		}
 
-		state.data2[symnro] = ro
-		state.data2[symnrelro] = relro
+		state.data[symnro] = ro
+		state.data[symnrelro] = relro
 	}
 }
 
@@ -1349,9 +1342,7 @@
 	// Link context
 	ctxt *Link
 	// Data symbols bucketed by type.
-	data [sym.SXREF][]*sym.Symbol
-	// Data symbols bucketed by type.
-	data2 [sym.SXREF][]loader.Sym
+	data [sym.SXREF][]loader.Sym
 	// Max alignment for each flavor of data symbol.
 	dataMaxAlign [sym.SXREF]int32
 	// Overridden sym type
@@ -1394,10 +1385,10 @@
 	}
 }
 
-func (ctxt *Link) dodata2(symGroupType []sym.SymKind) {
+func (ctxt *Link) dodata(symGroupType []sym.SymKind) {
 
 	// Give zeros sized symbols space if necessary.
-	fixZeroSizedSymbols2(ctxt)
+	fixZeroSizedSymbols(ctxt)
 
 	// Collect data symbols by type into data.
 	state := dodataState{ctxt: ctxt, symGroupType: symGroupType}
@@ -1413,7 +1404,7 @@
 		if st <= sym.STEXT || st >= sym.SXREF {
 			continue
 		}
-		state.data2[st] = append(state.data2[st], s)
+		state.data[st] = append(state.data[st], s)
 
 		// Similarly with checking the onlist attr.
 		if ldr.AttrOnList(s) {
@@ -1431,10 +1422,10 @@
 	if ctxt.HeadType == objabi.Hdarwin {
 		machosymorder(ctxt)
 	}
-	state.dynreloc2(ctxt)
+	state.dynreloc(ctxt)
 
 	// Move any RO data with relocations to a separate section.
-	state.makeRelroForSharedLib2(ctxt)
+	state.makeRelroForSharedLib(ctxt)
 
 	// Set alignment for the symbol with the largest known index,
 	// so as to trigger allocation of the loader's internal
@@ -1445,11 +1436,11 @@
 
 	// Sort symbols.
 	var wg sync.WaitGroup
-	for symn := range state.data2 {
+	for symn := range state.data {
 		symn := sym.SymKind(symn)
 		wg.Add(1)
 		go func() {
-			state.data2[symn], state.dataMaxAlign[symn] = state.dodataSect2(ctxt, symn, state.data2[symn])
+			state.data[symn], state.dataMaxAlign[symn] = state.dodataSect(ctxt, symn, state.data[symn])
 			wg.Done()
 		}()
 	}
@@ -1458,7 +1449,7 @@
 	if ctxt.IsELF {
 		// Make .rela and .rela.plt contiguous, the ELF ABI requires this
 		// and Solaris actually cares.
-		syms := state.data2[sym.SELFROSECT]
+		syms := state.data[sym.SELFROSECT]
 		reli, plti := -1, -1
 		for i, s := range syms {
 			switch ldr.SymName(s) {
@@ -1487,7 +1478,7 @@
 			ldr.SetSymAlign(rel, int32(ctxt.Arch.RegSize))
 			ldr.SetSymAlign(plt, int32(ctxt.Arch.RegSize))
 		}
-		state.data2[sym.SELFROSECT] = syms
+		state.data[sym.SELFROSECT] = syms
 	}
 
 	if ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal {
@@ -1499,11 +1490,11 @@
 
 	// Create *sym.Section objects and assign symbols to sections for
 	// data/rodata (and related) symbols.
-	state.allocateDataSections2(ctxt)
+	state.allocateDataSections(ctxt)
 
 	// Create *sym.Section objects and assign symbols to sections for
 	// DWARF symbols.
-	state.allocateDwarfSections2(ctxt)
+	state.allocateDwarfSections(ctxt)
 
 	/* number the sections */
 	n := int16(1)
@@ -1534,11 +1525,11 @@
 // single symbol will be placed. Here "seg" is the segment into which
 // the section will go, "s" is the symbol to be placed into the new
 // section, and "rwx" contains permissions for the section.
-func (state *dodataState) allocateDataSectionForSym2(seg *sym.Segment, s loader.Sym, rwx int) *sym.Section {
+func (state *dodataState) allocateDataSectionForSym(seg *sym.Segment, s loader.Sym, rwx int) *sym.Section {
 	ldr := state.ctxt.loader
 	sname := ldr.SymName(s)
 	sect := addsection(ldr, state.ctxt.Arch, seg, sname, rwx)
-	sect.Align = state.symalign2(s)
+	sect.Align = symalign(ldr, s)
 	state.datsize = Rnd(state.datsize, int64(sect.Align))
 	sect.Vaddr = uint64(state.datsize)
 	return sect
@@ -1574,7 +1565,7 @@
 // "forceType" (if non-zero) contains a new sym type to apply to each
 // sym during the assignment, and "aligner" is a hook to call to
 // handle alignment during the assignment process.
-func (state *dodataState) assignDsymsToSection2(sect *sym.Section, syms []loader.Sym, forceType sym.SymKind, aligner func(state *dodataState, datsize int64, s loader.Sym) int64) {
+func (state *dodataState) assignDsymsToSection(sect *sym.Section, syms []loader.Sym, forceType sym.SymKind, aligner func(state *dodataState, datsize int64, s loader.Sym) int64) {
 	ldr := state.ctxt.loader
 	for _, s := range syms {
 		state.datsize = aligner(state, state.datsize, s)
@@ -1588,8 +1579,8 @@
 	sect.Length = uint64(state.datsize) - sect.Vaddr
 }
 
-func (state *dodataState) assignToSection2(sect *sym.Section, symn sym.SymKind, forceType sym.SymKind) {
-	state.assignDsymsToSection2(sect, state.data2[symn], forceType, aligndatsize2)
+func (state *dodataState) assignToSection(sect *sym.Section, symn sym.SymKind, forceType sym.SymKind) {
+	state.assignDsymsToSection(sect, state.data[symn], forceType, aligndatsize)
 	state.checkdatsize(symn)
 }
 
@@ -1599,10 +1590,10 @@
 // symbol name. "Seg" is the segment into which to place the new
 // section, "forceType" is the new sym.SymKind to assign to the symbol
 // within the section, and "rwx" holds section permissions.
-func (state *dodataState) allocateSingleSymSections2(seg *sym.Segment, symn sym.SymKind, forceType sym.SymKind, rwx int) {
+func (state *dodataState) allocateSingleSymSections(seg *sym.Segment, symn sym.SymKind, forceType sym.SymKind, rwx int) {
 	ldr := state.ctxt.loader
-	for _, s := range state.data2[symn] {
-		sect := state.allocateDataSectionForSym2(seg, s, rwx)
+	for _, s := range state.data[symn] {
+		sect := state.allocateDataSectionForSym(seg, s, rwx)
 		ldr.SetSymSect(s, sect)
 		state.setSymType(s, forceType)
 		ldr.SetSymValue(s, int64(uint64(state.datsize)-sect.Vaddr))
@@ -1619,16 +1610,16 @@
 // name to give to the new section, "forceType" (if non-zero) contains
 // a new sym type to apply to each sym during the assignment, and
 // "rwx" holds section permissions.
-func (state *dodataState) allocateNamedSectionAndAssignSyms2(seg *sym.Segment, secName string, symn sym.SymKind, forceType sym.SymKind, rwx int) *sym.Section {
+func (state *dodataState) allocateNamedSectionAndAssignSyms(seg *sym.Segment, secName string, symn sym.SymKind, forceType sym.SymKind, rwx int) *sym.Section {
 
 	sect := state.allocateNamedDataSection(seg, secName, []sym.SymKind{symn}, rwx)
-	state.assignDsymsToSection2(sect, state.data2[symn], forceType, aligndatsize2)
+	state.assignDsymsToSection(sect, state.data[symn], forceType, aligndatsize)
 	return sect
 }
 
 // allocateDataSections allocates sym.Section objects for data/rodata
 // (and related) symbols, and then assigns symbols to those sections.
-func (state *dodataState) allocateDataSections2(ctxt *Link) {
+func (state *dodataState) allocateDataSections(ctxt *Link) {
 	// Allocate sections.
 	// Data is processed before segtext, because we need
 	// to see all symbols in the .data and .bss sections in order
@@ -1643,15 +1634,15 @@
 		sym.SWINDOWS,
 	}
 	for _, symn := range writable {
-		state.allocateSingleSymSections2(&Segdata, symn, sym.SDATA, 06)
+		state.allocateSingleSymSections(&Segdata, symn, sym.SDATA, 06)
 	}
 	ldr := ctxt.loader
 
 	// .got (and .toc on ppc64)
-	if len(state.data2[sym.SELFGOT]) > 0 {
-		sect := state.allocateNamedSectionAndAssignSyms2(&Segdata, ".got", sym.SELFGOT, sym.SDATA, 06)
+	if len(state.data[sym.SELFGOT]) > 0 {
+		sect := state.allocateNamedSectionAndAssignSyms(&Segdata, ".got", sym.SELFGOT, sym.SDATA, 06)
 		if ctxt.IsPPC64() {
-			for _, s := range state.data2[sym.SELFGOT] {
+			for _, s := range state.data[sym.SELFGOT] {
 				// Resolve .TOC. symbol for this object file (ppc64)
 
 				toc := ldr.Lookup(".TOC.", int(ldr.SymVersion(s)))
@@ -1665,7 +1656,7 @@
 	}
 
 	/* pointer-free data */
-	sect := state.allocateNamedSectionAndAssignSyms2(&Segdata, ".noptrdata", sym.SNOPTRDATA, sym.SDATA, 06)
+	sect := state.allocateNamedSectionAndAssignSyms(&Segdata, ".noptrdata", sym.SNOPTRDATA, sym.SDATA, 06)
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.noptrdata", 0), sect)
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.enoptrdata", 0), sect)
 
@@ -1678,29 +1669,29 @@
 	}
 
 	if ctxt.HeadType == objabi.Haix {
-		if len(state.data2[sym.SINITARR]) > 0 {
+		if len(state.data[sym.SINITARR]) > 0 {
 			Errorf(nil, "XCOFF format doesn't allow .init_array section")
 		}
 	}
 
-	if hasinitarr && len(state.data2[sym.SINITARR]) > 0 {
-		state.allocateNamedSectionAndAssignSyms2(&Segdata, ".init_array", sym.SINITARR, sym.Sxxx, 06)
+	if hasinitarr && len(state.data[sym.SINITARR]) > 0 {
+		state.allocateNamedSectionAndAssignSyms(&Segdata, ".init_array", sym.SINITARR, sym.Sxxx, 06)
 	}
 
 	/* data */
-	sect = state.allocateNamedSectionAndAssignSyms2(&Segdata, ".data", sym.SDATA, sym.SDATA, 06)
+	sect = state.allocateNamedSectionAndAssignSyms(&Segdata, ".data", sym.SDATA, sym.SDATA, 06)
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.data", 0), sect)
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.edata", 0), sect)
 	dataGcEnd := state.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.
-	state.assignToSection2(sect, sym.SXCOFFTOC, sym.SDATA)
+	state.assignToSection(sect, sym.SXCOFFTOC, sym.SDATA)
 	state.checkdatsize(sym.SDATA)
 	sect.Length = uint64(state.datsize) - sect.Vaddr
 
 	/* bss */
-	sect = state.allocateNamedSectionAndAssignSyms2(&Segdata, ".bss", sym.SBSS, sym.Sxxx, 06)
+	sect = state.allocateNamedSectionAndAssignSyms(&Segdata, ".bss", sym.SBSS, sym.Sxxx, 06)
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.bss", 0), sect)
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.ebss", 0), sect)
 	bssGcEnd := state.datsize - int64(sect.Vaddr)
@@ -1715,26 +1706,26 @@
 		{"runtime.gcbss", sym.SBSS, bssGcEnd},
 	}
 	for _, g := range gcsToEmit {
-		var gc GCProg2
+		var gc GCProg
 		gc.Init(ctxt, g.symName)
-		for _, s := range state.data2[g.symKind] {
+		for _, s := range state.data[g.symKind] {
 			gc.AddSym(s)
 		}
 		gc.End(g.gcEnd)
 	}
 
 	/* pointer-free bss */
-	sect = state.allocateNamedSectionAndAssignSyms2(&Segdata, ".noptrbss", sym.SNOPTRBSS, sym.Sxxx, 06)
+	sect = state.allocateNamedSectionAndAssignSyms(&Segdata, ".noptrbss", sym.SNOPTRBSS, sym.Sxxx, 06)
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.noptrbss", 0), sect)
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.enoptrbss", 0), sect)
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.end", 0), sect)
 
 	// Coverage instrumentation counters for libfuzzer.
-	if len(state.data2[sym.SLIBFUZZER_EXTRA_COUNTER]) > 0 {
-		state.allocateNamedSectionAndAssignSyms2(&Segdata, "__libfuzzer_extra_counters", sym.SLIBFUZZER_EXTRA_COUNTER, sym.Sxxx, 06)
+	if len(state.data[sym.SLIBFUZZER_EXTRA_COUNTER]) > 0 {
+		state.allocateNamedSectionAndAssignSyms(&Segdata, "__libfuzzer_extra_counters", sym.SLIBFUZZER_EXTRA_COUNTER, sym.Sxxx, 06)
 	}
 
-	if len(state.data2[sym.STLSBSS]) > 0 {
+	if len(state.data[sym.STLSBSS]) > 0 {
 		var sect *sym.Section
 		// FIXME: not clear why it is sometimes necessary to suppress .tbss section creation.
 		if (ctxt.IsELF || ctxt.HeadType == objabi.Haix) && (ctxt.LinkMode == LinkExternal || !*FlagD) {
@@ -1745,8 +1736,8 @@
 		}
 		state.datsize = 0
 
-		for _, s := range state.data2[sym.STLSBSS] {
-			state.datsize = aligndatsize2(state, state.datsize, s)
+		for _, s := range state.data[sym.STLSBSS] {
+			state.datsize = aligndatsize(state, state.datsize, s)
 			if sect != nil {
 				ldr.SetSymSect(s, sect)
 			}
@@ -1781,11 +1772,11 @@
 	state.datsize = 0
 
 	/* read-only executable ELF, Mach-O sections */
-	if len(state.data2[sym.STEXT]) != 0 {
-		culprit := ldr.SymName(state.data2[sym.STEXT][0])
+	if len(state.data[sym.STEXT]) != 0 {
+		culprit := ldr.SymName(state.data[sym.STEXT][0])
 		Errorf(nil, "dodata found an sym.STEXT symbol: %s", culprit)
 	}
-	state.allocateSingleSymSections2(&Segtext, sym.SELFRXSECT, sym.SRODATA, 04)
+	state.allocateSingleSymSections(&Segtext, sym.SELFRXSECT, sym.SRODATA, 04)
 
 	/* read-only data */
 	sect = state.allocateNamedDataSection(segro, ".rodata", sym.ReadOnly, 04)
@@ -1797,19 +1788,19 @@
 	}
 	for _, symn := range sym.ReadOnly {
 		symnStartValue := state.datsize
-		state.assignToSection2(sect, symn, sym.SRODATA)
+		state.assignToSection(sect, symn, sym.SRODATA)
 		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.
-			xcoffUpdateOuterSize2(ctxt, state.datsize-symnStartValue, symn)
+			xcoffUpdateOuterSize(ctxt, state.datsize-symnStartValue, symn)
 		}
 	}
 
 	/* read-only ELF, Mach-O sections */
-	state.allocateSingleSymSections2(segro, sym.SELFROSECT, sym.SRODATA, 04)
-	state.allocateSingleSymSections2(segro, sym.SMACHOPLT, sym.SRODATA, 04)
+	state.allocateSingleSymSections(segro, sym.SELFROSECT, sym.SRODATA, 04)
+	state.allocateSingleSymSections(segro, sym.SMACHOPLT, sym.SRODATA, 04)
 
 	// 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
@@ -1873,19 +1864,19 @@
 			symn := sym.RelROMap[symnro]
 			symnStartValue := state.datsize
 
-			for _, s := range state.data2[symn] {
+			for _, s := range state.data[symn] {
 				outer := ldr.OuterSym(s)
 				if s != 0 && ldr.SymSect(outer) != nil && ldr.SymSect(outer) != sect {
 					ctxt.Errorf(s, "s.Outer (%s) in different section from s, %s != %s", ldr.SymName(outer), ldr.SymSect(outer).Name, sect.Name)
 				}
 			}
-			state.assignToSection2(sect, symn, sym.SRODATA)
+			state.assignToSection(sect, symn, sym.SRODATA)
 			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.
-				xcoffUpdateOuterSize2(ctxt, state.datsize-symnStartValue, symn)
+				xcoffUpdateOuterSize(ctxt, state.datsize-symnStartValue, symn)
 			}
 		}
 
@@ -1903,22 +1894,22 @@
 	sect.Length = uint64(state.datsize) - sect.Vaddr
 
 	/* itablink */
-	sect = state.allocateNamedSectionAndAssignSyms2(seg, genrelrosecname(".itablink"), sym.SITABLINK, sym.Sxxx, relroSecPerm)
+	sect = state.allocateNamedSectionAndAssignSyms(seg, genrelrosecname(".itablink"), sym.SITABLINK, sym.Sxxx, relroSecPerm)
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.itablink", 0), sect)
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.eitablink", 0), sect)
 	if ctxt.HeadType == objabi.Haix {
 		// Store .itablink size because its symbols are wrapped
 		// under an outer symbol: runtime.itablink.
-		xcoffUpdateOuterSize2(ctxt, int64(sect.Length), sym.SITABLINK)
+		xcoffUpdateOuterSize(ctxt, int64(sect.Length), sym.SITABLINK)
 	}
 
 	/* gosymtab */
-	sect = state.allocateNamedSectionAndAssignSyms2(seg, genrelrosecname(".gosymtab"), sym.SSYMTAB, sym.SRODATA, relroSecPerm)
+	sect = state.allocateNamedSectionAndAssignSyms(seg, genrelrosecname(".gosymtab"), sym.SSYMTAB, sym.SRODATA, relroSecPerm)
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.symtab", 0), sect)
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.esymtab", 0), sect)
 
 	/* gopclntab */
-	sect = state.allocateNamedSectionAndAssignSyms2(seg, genrelrosecname(".gopclntab"), sym.SPCLNTAB, sym.SRODATA, relroSecPerm)
+	sect = state.allocateNamedSectionAndAssignSyms(seg, genrelrosecname(".gopclntab"), sym.SPCLNTAB, sym.SRODATA, relroSecPerm)
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pclntab", 0), sect)
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.epclntab", 0), sect)
 
@@ -1929,35 +1920,35 @@
 
 	siz := 0
 	for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ {
-		siz += len(state.data2[symn])
+		siz += len(state.data[symn])
 	}
-	ctxt.datap2 = make([]loader.Sym, 0, siz)
+	ctxt.datap = make([]loader.Sym, 0, siz)
 	for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ {
-		ctxt.datap2 = append(ctxt.datap2, state.data2[symn]...)
+		ctxt.datap = append(ctxt.datap, state.data[symn]...)
 	}
 }
 
 // allocateDwarfSections allocates sym.Section objects for DWARF
 // symbols, and assigns symbols to sections.
-func (state *dodataState) allocateDwarfSections2(ctxt *Link) {
+func (state *dodataState) allocateDwarfSections(ctxt *Link) {
 
 	alignOne := func(state *dodataState, datsize int64, s loader.Sym) int64 { return datsize }
 
 	ldr := ctxt.loader
-	for i := 0; i < len(dwarfp2); i++ {
+	for i := 0; i < len(dwarfp); i++ {
 		// First the section symbol.
-		s := dwarfp2[i].secSym()
+		s := dwarfp[i].secSym()
 		sect := state.allocateNamedDataSection(&Segdwarf, ldr.SymName(s), []sym.SymKind{}, 04)
 		ldr.SetSymSect(s, sect)
-		sect.Sym2 = sym.LoaderSym(s)
+		sect.Sym = sym.LoaderSym(s)
 		curType := ldr.SymType(s)
 		state.setSymType(s, sym.SRODATA)
 		ldr.SetSymValue(s, int64(uint64(state.datsize)-sect.Vaddr))
 		state.datsize += ldr.SymSize(s)
 
 		// Then any sub-symbols for the section symbol.
-		subSyms := dwarfp2[i].subSyms()
-		state.assignDsymsToSection2(sect, subSyms, sym.SRODATA, alignOne)
+		subSyms := dwarfp[i].subSyms()
+		state.assignDsymsToSection(sect, subSyms, sym.SRODATA, alignOne)
 
 		for j := 0; j < len(subSyms); j++ {
 			s := subSyms[j]
@@ -1978,7 +1969,7 @@
 	sym  loader.Sym
 }
 
-func (state *dodataState) dodataSect2(ctxt *Link, symn sym.SymKind, syms []loader.Sym) (result []loader.Sym, maxAlign int32) {
+func (state *dodataState) dodataSect(ctxt *Link, symn sym.SymKind, syms []loader.Sym) (result []loader.Sym, maxAlign int32) {
 	var head, tail loader.Sym
 	ldr := ctxt.loader
 	sl := make([]symNameSize, len(syms))
@@ -2045,7 +2036,7 @@
 	for k := range sl {
 		s := sl[k].sym
 		if s != head && s != tail {
-			align := state.symalign2(s)
+			align := symalign(ldr, s)
 			if maxAlign < align {
 				maxAlign = align
 			}
@@ -2076,9 +2067,9 @@
 	s.SetData([]byte(data))
 	s.SetSize(int64(len(data)))
 
-	ctxt.Textp2 = append(ctxt.Textp2, 0)
-	copy(ctxt.Textp2[1:], ctxt.Textp2)
-	ctxt.Textp2[0] = s.Sym()
+	ctxt.Textp = append(ctxt.Textp, 0)
+	copy(ctxt.Textp[1:], ctxt.Textp)
+	ctxt.Textp[0] = s.Sym()
 }
 
 func (ctxt *Link) buildinfo() {
@@ -2093,6 +2084,9 @@
 	ldr := ctxt.loader
 	s := ldr.CreateSymForUpdate(".go.buildinfo", 0)
 	s.SetReachable(true)
+	// On AIX, .go.buildinfo must be in the symbol table as
+	// it has relocations.
+	s.SetNotInSymbolTable(!ctxt.IsAIX())
 	s.SetType(sym.SBUILDINFO)
 	s.SetAlign(16)
 	// The \xff is invalid UTF-8, meant to make it less likely
@@ -2145,16 +2139,16 @@
 		etext := ldr.LookupOrCreateSym("runtime.etext", 0)
 		ldr.SetSymSect(etext, sect)
 
-		ctxt.Textp2 = append(ctxt.Textp2, etext, 0)
-		copy(ctxt.Textp2[1:], ctxt.Textp2)
-		ctxt.Textp2[0] = text
+		ctxt.Textp = append(ctxt.Textp, etext, 0)
+		copy(ctxt.Textp[1:], ctxt.Textp)
+		ctxt.Textp[0] = text
 	}
 
 	va := uint64(*FlagTextAddr)
 	n := 1
 	sect.Vaddr = va
 	ntramps := 0
-	for _, s := range ctxt.Textp2 {
+	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
@@ -2177,9 +2171,9 @@
 
 	// merge tramps into Textp, keeping Textp in address order
 	if ntramps != 0 {
-		newtextp := make([]loader.Sym, 0, len(ctxt.Textp2)+ntramps)
+		newtextp := make([]loader.Sym, 0, len(ctxt.Textp)+ntramps)
 		i := 0
-		for _, s := range ctxt.Textp2 {
+		for _, s := range ctxt.Textp {
 			for ; i < ntramps && ldr.SymValue(ctxt.tramps[i]) < ldr.SymValue(s); i++ {
 				newtextp = append(newtextp, ctxt.tramps[i])
 			}
@@ -2187,7 +2181,7 @@
 		}
 		newtextp = append(newtextp, ctxt.tramps[i:ntramps]...)
 
-		ctxt.Textp2 = newtextp
+		ctxt.Textp = newtextp
 	}
 }
 
@@ -2412,7 +2406,7 @@
 		}
 	}
 
-	for _, s := range ctxt.datap2 {
+	for _, s := range ctxt.datap {
 		if sect := ldr.SymSect(s); sect != nil {
 			ldr.AddToSymValue(s, int64(sect.Vaddr))
 		}
@@ -2422,7 +2416,7 @@
 		}
 	}
 
-	for _, si := range dwarfp2 {
+	for _, si := range dwarfp {
 		for _, s := range si.syms {
 			if sect := ldr.SymSect(s); sect != nil {
 				ldr.AddToSymValue(s, int64(sect.Vaddr))
@@ -2445,8 +2439,8 @@
 		ldr.SetSymValue(s, int64(sect.Vaddr+16))
 	}
 
-	ctxt.xdefine2("runtime.text", sym.STEXT, int64(text.Vaddr))
-	ctxt.xdefine2("runtime.etext", sym.STEXT, int64(lasttext.Vaddr+lasttext.Length))
+	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
@@ -2459,41 +2453,41 @@
 		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.xdefine2(symname, sym.STEXT, int64(sect.Vaddr))
+			ctxt.xdefine(symname, sym.STEXT, int64(sect.Vaddr))
 		}
 		n++
 	}
 
-	ctxt.xdefine2("runtime.rodata", sym.SRODATA, int64(rodata.Vaddr))
-	ctxt.xdefine2("runtime.erodata", sym.SRODATA, int64(rodata.Vaddr+rodata.Length))
-	ctxt.xdefine2("runtime.types", sym.SRODATA, int64(types.Vaddr))
-	ctxt.xdefine2("runtime.etypes", sym.SRODATA, int64(types.Vaddr+types.Length))
-	ctxt.xdefine2("runtime.itablink", sym.SRODATA, int64(itablink.Vaddr))
-	ctxt.xdefine2("runtime.eitablink", sym.SRODATA, int64(itablink.Vaddr+itablink.Length))
+	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 := ldr.Lookup("runtime.gcdata", 0)
 	ldr.SetAttrLocal(s, true)
-	ctxt.xdefine2("runtime.egcdata", sym.SRODATA, ldr.SymAddr(s)+ldr.SymSize(s))
+	ctxt.xdefine("runtime.egcdata", sym.SRODATA, ldr.SymAddr(s)+ldr.SymSize(s))
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.egcdata", 0), ldr.SymSect(s))
 
 	s = ldr.LookupOrCreateSym("runtime.gcbss", 0)
 	ldr.SetAttrLocal(s, true)
-	ctxt.xdefine2("runtime.egcbss", sym.SRODATA, ldr.SymAddr(s)+ldr.SymSize(s))
+	ctxt.xdefine("runtime.egcbss", sym.SRODATA, ldr.SymAddr(s)+ldr.SymSize(s))
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.egcbss", 0), ldr.SymSect(s))
 
-	ctxt.xdefine2("runtime.symtab", sym.SRODATA, int64(symtab.Vaddr))
-	ctxt.xdefine2("runtime.esymtab", sym.SRODATA, int64(symtab.Vaddr+symtab.Length))
-	ctxt.xdefine2("runtime.pclntab", sym.SRODATA, int64(pclntab.Vaddr))
-	ctxt.xdefine2("runtime.epclntab", sym.SRODATA, int64(pclntab.Vaddr+pclntab.Length))
-	ctxt.xdefine2("runtime.noptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr))
-	ctxt.xdefine2("runtime.enoptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr+noptr.Length))
-	ctxt.xdefine2("runtime.bss", sym.SBSS, int64(bss.Vaddr))
-	ctxt.xdefine2("runtime.ebss", sym.SBSS, int64(bss.Vaddr+bss.Length))
-	ctxt.xdefine2("runtime.data", sym.SDATA, int64(data.Vaddr))
-	ctxt.xdefine2("runtime.edata", sym.SDATA, int64(data.Vaddr+data.Length))
-	ctxt.xdefine2("runtime.noptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr))
-	ctxt.xdefine2("runtime.enoptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length))
-	ctxt.xdefine2("runtime.end", sym.SBSS, int64(Segdata.Vaddr+Segdata.Length))
+	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))
 
 	if ctxt.IsSolaris() {
 		// On Solaris, in the runtime it sets the external names of the
@@ -2505,9 +2499,9 @@
 		ldr.SetSymExtname(etext, "runtime.etext")
 		ldr.SetSymExtname(edata, "runtime.edata")
 		ldr.SetSymExtname(end, "runtime.end")
-		ctxt.xdefine2("_etext", ldr.SymType(etext), ldr.SymValue(etext))
-		ctxt.xdefine2("_edata", ldr.SymType(edata), ldr.SymValue(edata))
-		ctxt.xdefine2("_end", ldr.SymType(end), ldr.SymValue(end))
+		ctxt.xdefine("_etext", ldr.SymType(etext), ldr.SymValue(etext))
+		ctxt.xdefine("_edata", ldr.SymType(edata), ldr.SymValue(edata))
+		ctxt.xdefine("_end", ldr.SymType(end), ldr.SymValue(end))
 		ldr.SetSymSect(ldr.Lookup("_etext", 0), ldr.SymSect(etext))
 		ldr.SetSymSect(ldr.Lookup("_edata", 0), ldr.SymSect(edata))
 		ldr.SetSymSect(ldr.Lookup("_end", 0), ldr.SymSect(end))
diff --git a/src/cmd/link/internal/ld/data2.go b/src/cmd/link/internal/ld/data2.go
deleted file mode 100644
index d4503a4..0000000
--- a/src/cmd/link/internal/ld/data2.go
+++ /dev/null
@@ -1,518 +0,0 @@
-// Copyright 2020 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/link/internal/loader"
-	"cmd/link/internal/sym"
-	"fmt"
-	"log"
-	"strings"
-	"sync"
-)
-
-// Temporary dumping around for sym.Symbol version of helper
-// functions in dodata(), still being used for some archs/oses.
-// FIXME: get rid of this file when dodata() is completely
-// converted.
-
-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
-}
-
-// 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 relocsym2(target *Target, ldr *loader.Loader, err *ErrorReporter, syms *ArchSyms, s *sym.Symbol) {
-	if len(s.R) == 0 {
-		return
-	}
-	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 target.IsShared() || target.IsPlugin() {
-				if r.Sym.Name == "main.main" || (!target.IsPlugin() && 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 {
-				err.errorUnresolved2(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 !target.IsSolaris() && !target.IsDarwin() && !target.IsAIX() && r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT && !target.IsDynlinkingGo() && !r.Sym.Attr.SubSymbol() {
-			if !(target.IsPPC64() && target.IsExternal() && 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(target.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 target.IsExternal() {
-			r.InitExt()
-		}
-
-		// TODO(mundaym): remove this special case - see issue 14218.
-		if target.IsS390X() {
-			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(target.Arch.ByteOrder.Uint16(s.P[off:]))
-			case 4:
-				o = int64(target.Arch.ByteOrder.Uint32(s.P[off:]))
-			case 8:
-				o = int64(target.Arch.ByteOrder.Uint64(s.P[off:]))
-			}
-			if offset, ok := thearch.Archreloc(target, syms, r, s, o); ok {
-				o = offset
-			} else {
-				Errorf(s, "unknown reloc to %v: %d (%s)", r.Sym.Name, r.Type, sym.RelocName(target.Arch, r.Type))
-			}
-		case objabi.R_TLS_LE:
-			if target.IsExternal() && target.IsElf() {
-				r.Done = false
-				if r.Sym == nil {
-					r.Sym = syms.Tlsg
-				}
-				r.Xsym = r.Sym
-				r.Xadd = r.Add
-				o = 0
-				if !target.IsAMD64() {
-					o = r.Add
-				}
-				break
-			}
-
-			if target.IsElf() && target.IsARM() {
-				// 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 target.IsElf() || target.IsPlan9() || target.IsDarwin() {
-				o = int64(syms.Tlsoffset) + r.Add
-			} else if target.IsWindows() {
-				o = r.Add
-			} else {
-				log.Fatalf("unexpected R_TLS_LE relocation for %v", target.HeadType)
-			}
-		case objabi.R_TLS_IE:
-			if target.IsExternal() && target.IsElf() {
-				r.Done = false
-				if r.Sym == nil {
-					r.Sym = syms.Tlsg
-				}
-				r.Xsym = r.Sym
-				r.Xadd = r.Add
-				o = 0
-				if !target.IsAMD64() {
-					o = r.Add
-				}
-				break
-			}
-			if target.IsPIE() && target.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", target.Arch.Family)
-				}
-				thearch.TLSIEtoLE(s.P, int(off), int(r.Siz))
-				o = int64(syms.Tlsoffset)
-				// TODO: o += r.Add when !target.IsAmd64()?
-				// 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 target.IsExternal() && 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 target.IsElf() {
-					if target.IsAMD64() {
-						o = 0
-					}
-				} else if target.IsDarwin() {
-					if rs.Type != sym.SHOSTOBJ {
-						o += Symaddr(rs)
-					}
-				} else if target.IsWindows() {
-					// nothing to do
-				} else if target.IsAIX() {
-					o = Symaddr(r.Sym) + r.Add
-				} else {
-					Errorf(s, "unhandled pcrel relocation to %s on %v", rs.Name, target.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 target.IsAIX() && 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(target, ldr, 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 && target.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 target.IsExternal() {
-				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 target.IsDarwin() {
-					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 !target.IsWindows() {
-					r.Type = objabi.R_ADDR
-				}
-
-				r.Xsym = r.Sym.Sect.Sym
-				r.Xadd = r.Add + Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr)
-
-				o = r.Xadd
-				if target.IsElf() && target.IsAMD64() {
-					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.
-			u := ldr.SymUnit(loader.Sym(r.Sym.SymIdx))
-			o = Symaddr(r.Sym) + r.Add - Symaddr(ldr.Syms[u.Textp2[0]])
-
-			// r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call.
-		case objabi.R_GOTPCREL:
-			if target.IsDynlinkingGo() && target.IsDarwin() && 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 target.IsExternal() && r.Sym != nil && r.Sym.Type == sym.SUNDEFEXT {
-				// pass through to the external linker.
-				r.Done = false
-				r.Xadd = 0
-				if target.IsElf() {
-					r.Xadd -= int64(r.Siz)
-				}
-				r.Xsym = r.Sym
-				o = 0
-				break
-			}
-			if target.IsExternal() && 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 target.IsElf() {
-					if target.IsAMD64() {
-						o = 0
-					}
-				} else if target.IsDarwin() {
-					if r.Type == objabi.R_CALL {
-						if target.IsExternal() && rs.Type == sym.SDYNIMPORT {
-							if target.IsAMD64() {
-								// 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 target.IsWindows() && target.IsAMD64() { // 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, target.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 !target.IsAIX() {
-				Errorf(s, "find XCOFF R_REF on non-XCOFF files")
-			}
-			if !target.IsExternal() {
-				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 target.IsPPC64() || target.IsS390X() {
-			r.InitExt()
-			if r.Variant != sym.RV_NONE {
-				o = thearch.Archrelocvariant(target, syms, 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(target.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)
-			target.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)
-			target.Arch.ByteOrder.PutUint32(s.P[off:], uint32(fl))
-		case 8:
-			target.Arch.ByteOrder.PutUint64(s.P[off:], uint64(o))
-		}
-	}
-}
-
-func (ctxt *Link) reloc2() {
-	var wg sync.WaitGroup
-	target := &ctxt.Target
-	ldr := ctxt.loader
-	reporter := &ctxt.ErrorReporter
-	syms := &ctxt.ArchSyms
-	wg.Add(3)
-	go func() {
-		if !ctxt.IsWasm() { // On Wasm, text relocations are applied in Asmb2.
-			for _, s := range ctxt.Textp {
-				relocsym2(target, ldr, reporter, syms, s)
-			}
-		}
-		wg.Done()
-	}()
-	go func() {
-		for _, s := range ctxt.datap {
-			relocsym2(target, ldr, reporter, syms, s)
-		}
-		wg.Done()
-	}()
-	go func() {
-		for _, si := range dwarfp {
-			for _, s := range si.syms {
-				relocsym2(target, ldr, reporter, syms, s)
-			}
-		}
-		wg.Done()
-	}()
-	wg.Wait()
-}
diff --git a/src/cmd/link/internal/ld/data_test.go b/src/cmd/link/internal/ld/data_test.go
new file mode 100644
index 0000000..7c46307
--- /dev/null
+++ b/src/cmd/link/internal/ld/data_test.go
@@ -0,0 +1,92 @@
+// Copyright 2020 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/link/internal/loader"
+	"testing"
+)
+
+func setUpContext(arch *sys.Arch, iself bool, ht objabi.HeadType, bm, lm string) *Link {
+	ctxt := linknew(arch)
+	edummy := func(str string, off int) {}
+	ctxt.HeadType = ht
+	er := loader.ErrorReporter{}
+	ctxt.loader = loader.NewLoader(0, edummy, &er)
+	ctxt.BuildMode.Set(bm)
+	ctxt.LinkMode.Set(lm)
+	ctxt.IsELF = iself
+	ctxt.mustSetHeadType()
+	ctxt.setArchSyms()
+	return ctxt
+}
+
+// Make sure the addgotsym properly increases the symbols.
+func TestAddGotSym(t *testing.T) {
+	tests := []struct {
+		arch    *sys.Arch
+		ht      objabi.HeadType
+		bm, lm  string
+		rel     string
+		relsize int
+		gotsize int
+	}{
+		{
+			arch:    sys.Arch386,
+			ht:      objabi.Hlinux,
+			bm:      "pie",
+			lm:      "internal",
+			rel:     ".rel",
+			relsize: 2 * sys.Arch386.PtrSize,
+			gotsize: sys.Arch386.PtrSize,
+		},
+		{
+			arch:    sys.ArchAMD64,
+			ht:      objabi.Hlinux,
+			bm:      "pie",
+			lm:      "internal",
+			rel:     ".rela",
+			relsize: 3 * sys.ArchAMD64.PtrSize,
+			gotsize: sys.ArchAMD64.PtrSize,
+		},
+		{
+			arch:    sys.ArchAMD64,
+			ht:      objabi.Hdarwin,
+			bm:      "pie",
+			lm:      "external",
+			gotsize: sys.ArchAMD64.PtrSize,
+		},
+	}
+
+	// Save the architecture as we're going to set it on each test run.
+	origArch := objabi.GOARCH
+	defer func() {
+		objabi.GOARCH = origArch
+	}()
+
+	for i, test := range tests {
+		iself := len(test.rel) != 0
+		objabi.GOARCH = test.arch.Name
+		ctxt := setUpContext(test.arch, iself, test.ht, test.bm, test.lm)
+		foo := ctxt.loader.CreateSymForUpdate("foo", 0)
+		ctxt.loader.CreateExtSym("bar", 0)
+		AddGotSym(&ctxt.Target, ctxt.loader, &ctxt.ArchSyms, foo.Sym(), 0)
+
+		if iself {
+			rel := ctxt.loader.Lookup(test.rel, 0)
+			if rel == 0 {
+				t.Fatalf("[%d] could not find symbol: %q", i, test.rel)
+			}
+			if s := ctxt.loader.SymSize(rel); s != int64(test.relsize) {
+				t.Fatalf("[%d] expected ldr.Size(%q) == %v, got %v", i, test.rel, test.relsize, s)
+			}
+		}
+		if s := ctxt.loader.SymSize(ctxt.loader.Lookup(".got", 0)); s != int64(test.gotsize) {
+			t.Fatalf(`[%d] expected ldr.Size(".got") == %v, got %v`, i, test.gotsize, s)
+		}
+	}
+}
diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go
index 7c58a62..d59b1f2 100644
--- a/src/cmd/link/internal/ld/deadcode.go
+++ b/src/cmd/link/internal/ld/deadcode.go
@@ -5,42 +5,27 @@
 package ld
 
 import (
-	"bytes"
 	"cmd/internal/goobj2"
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"cmd/link/internal/loader"
 	"cmd/link/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 deadcodePass struct {
 	ctxt *Link
 	ldr  *loader.Loader
-	wq   workQueue
+	wq   heap // work queue, using min-heap for beter locality
 
 	ifaceMethod     map[methodsig]bool // methods declared in reached interfaces
 	markableMethods []methodref        // methods of reached types
 	reflectSeen     bool               // whether we have seen a reflect method call
+
+	methodsigstmp []methodsig // scratch buffer for decoding method signatures
 }
 
 func (d *deadcodePass) init() {
@@ -49,7 +34,6 @@
 	if objabi.Fieldtrack_enabled != 0 {
 		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
@@ -110,6 +94,7 @@
 }
 
 func (d *deadcodePass) flood() {
+	var methods []methodref
 	for !d.wq.empty() {
 		symIdx := d.wq.pop()
 
@@ -123,14 +108,14 @@
 			if len(p) != 0 && decodetypeKind(d.ctxt.Arch, p)&kindMask == kindInterface {
 				for _, sig := range d.decodeIfaceMethods(d.ldr, d.ctxt.Arch, symIdx, &relocs) {
 					if d.ctxt.Debugvlog > 1 {
-						d.ctxt.Logf("reached iface method: %s\n", sig)
+						d.ctxt.Logf("reached iface method: %v\n", sig)
 					}
 					d.ifaceMethod[sig] = true
 				}
 			}
 		}
 
-		var methods []methodref
+		methods = methods[:0]
 		for i := 0; i < relocs.Count(); i++ {
 			r := relocs.At2(i)
 			t := r.Type()
@@ -191,6 +176,9 @@
 			}
 			for i, m := range methodsigs {
 				methods[i].m = m
+				if d.ctxt.Debugvlog > 1 {
+					d.ctxt.Logf("markable method: %v of sym %v %s\n", m, symIdx, d.ldr.SymName(symIdx))
+				}
 			}
 			d.markableMethods = append(d.markableMethods, methods...)
 		}
@@ -316,6 +304,12 @@
 	}
 }
 
+// methodsig is a typed method signature (name + type).
+type methodsig struct {
+	name string
+	typ  loader.Sym // type descriptor symbol of the function
+}
+
 // 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.
@@ -326,52 +320,27 @@
 }
 
 func (m methodref) isExported() bool {
-	for _, r := range m.m {
+	for _, r := range m.m.name {
 		return unicode.IsUpper(r)
 	}
 	panic("methodref has no signature")
 }
 
-// decodeMethodSig2 decodes an array of method signature information.
+// 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 (d *deadcodePass) decodeMethodSig(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs, off, size, count int) []methodsig {
-	var buf bytes.Buffer
-	var methods []methodsig
+	if cap(d.methodsigstmp) < count {
+		d.methodsigstmp = append(d.methodsigstmp[:0], make([]methodsig, count)...)
+	}
+	var methods = d.methodsigstmp[:count]
 	for i := 0; i < count; i++ {
-		buf.WriteString(decodetypeName(ldr, symIdx, relocs, off))
-		mtypSym := decodeRelocSym(ldr, symIdx, relocs, int32(off+4))
-		// FIXME: add some sort of caching here, since we may see some of the
-		// same symbols over time for param types.
-		mrelocs := ldr.Relocs(mtypSym)
-		mp := ldr.Data(mtypSym)
-
-		buf.WriteRune('(')
-		inCount := decodetypeFuncInCount(arch, mp)
-		for i := 0; i < inCount; i++ {
-			if i > 0 {
-				buf.WriteString(", ")
-			}
-			a := decodetypeFuncInType(ldr, arch, mtypSym, &mrelocs, i)
-			buf.WriteString(ldr.SymName(a))
-		}
-		buf.WriteString(") (")
-		outCount := decodetypeFuncOutCount(arch, mp)
-		for i := 0; i < outCount; i++ {
-			if i > 0 {
-				buf.WriteString(", ")
-			}
-			a := decodetypeFuncOutType(ldr, arch, mtypSym, &mrelocs, i)
-			buf.WriteString(ldr.SymName(a))
-		}
-		buf.WriteRune(')')
-
+		methods[i].name = decodetypeName(ldr, symIdx, relocs, off)
+		methods[i].typ = decodeRelocSym(ldr, symIdx, relocs, int32(off+4))
 		off += size
-		methods = append(methods, methodsig(buf.String()))
-		buf.Reset()
 	}
 	return methods
 }
diff --git a/src/cmd/link/internal/ld/decodesym.go b/src/cmd/link/internal/ld/decodesym.go
index e9c87ef..3211a4e 100644
--- a/src/cmd/link/internal/ld/decodesym.go
+++ b/src/cmd/link/internal/ld/decodesym.go
@@ -90,10 +90,6 @@
 	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
diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go
index 8df03d7..617f968 100644
--- a/src/cmd/link/internal/ld/dwarf.go
+++ b/src/cmd/link/internal/ld/dwarf.go
@@ -27,13 +27,13 @@
 	"strings"
 )
 
-// dwctxt2 is a wrapper intended to satisfy the method set of
+// dwctxt is a wrapper intended to satisfy the method set of
 // dwarf.Context, so that functions like dwarf.PutAttrs will work with
 // DIEs that use loader.Sym as opposed to *sym.Symbol. It is also
 // being used as a place to store tables/maps that are useful as part
 // of type conversion (this is just a convenience; it would be easy to
 // split these things out into another type if need be).
-type dwctxt2 struct {
+type dwctxt struct {
 	linkctxt *Link
 	ldr      *loader.Loader
 	arch     *sys.Arch
@@ -59,8 +59,8 @@
 	uintptrInfoSym   loader.Sym
 }
 
-func newdwctxt2(linkctxt *Link, forTypeGen bool) dwctxt2 {
-	d := dwctxt2{
+func newdwctxt(linkctxt *Link, forTypeGen bool) dwctxt {
+	d := dwctxt{
 		linkctxt: linkctxt,
 		ldr:      linkctxt.loader,
 		arch:     linkctxt.Arch,
@@ -79,33 +79,33 @@
 type dwSym loader.Sym
 
 func (s dwSym) Length(dwarfContext interface{}) int64 {
-	l := dwarfContext.(dwctxt2).ldr
+	l := dwarfContext.(dwctxt).ldr
 	return int64(len(l.Data(loader.Sym(s))))
 }
 
-func (c dwctxt2) PtrSize() int {
+func (c dwctxt) PtrSize() int {
 	return c.arch.PtrSize
 }
 
-func (c dwctxt2) AddInt(s dwarf.Sym, size int, i int64) {
+func (c dwctxt) AddInt(s dwarf.Sym, size int, i int64) {
 	ds := loader.Sym(s.(dwSym))
 	dsu := c.ldr.MakeSymbolUpdater(ds)
 	dsu.AddUintXX(c.arch, uint64(i), size)
 }
 
-func (c dwctxt2) AddBytes(s dwarf.Sym, b []byte) {
+func (c dwctxt) AddBytes(s dwarf.Sym, b []byte) {
 	ds := loader.Sym(s.(dwSym))
 	dsu := c.ldr.MakeSymbolUpdater(ds)
 	dsu.AddBytes(b)
 }
 
-func (c dwctxt2) AddString(s dwarf.Sym, v string) {
+func (c dwctxt) AddString(s dwarf.Sym, v string) {
 	ds := loader.Sym(s.(dwSym))
 	dsu := c.ldr.MakeSymbolUpdater(ds)
 	dsu.Addstring(v)
 }
 
-func (c dwctxt2) AddAddress(s dwarf.Sym, data interface{}, value int64) {
+func (c dwctxt) AddAddress(s dwarf.Sym, data interface{}, value int64) {
 	ds := loader.Sym(s.(dwSym))
 	dsu := c.ldr.MakeSymbolUpdater(ds)
 	if value != 0 {
@@ -115,7 +115,7 @@
 	dsu.AddAddrPlus(c.arch, tgtds, value)
 }
 
-func (c dwctxt2) AddCURelativeAddress(s dwarf.Sym, data interface{}, value int64) {
+func (c dwctxt) AddCURelativeAddress(s dwarf.Sym, data interface{}, value int64) {
 	ds := loader.Sym(s.(dwSym))
 	dsu := c.ldr.MakeSymbolUpdater(ds)
 	if value != 0 {
@@ -125,7 +125,7 @@
 	dsu.AddCURelativeAddrPlus(c.arch, tgtds, value)
 }
 
-func (c dwctxt2) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) {
+func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) {
 	ds := loader.Sym(s.(dwSym))
 	dsu := c.ldr.MakeSymbolUpdater(ds)
 	tds := loader.Sym(t.(dwSym))
@@ -137,7 +137,7 @@
 	dsu.AddSymRef(c.arch, tds, ofs, objabi.R_ADDROFF, size)
 }
 
-func (c dwctxt2) AddDWARFAddrSectionOffset(s dwarf.Sym, t interface{}, ofs int64) {
+func (c dwctxt) AddDWARFAddrSectionOffset(s dwarf.Sym, t interface{}, ofs int64) {
 	size := 4
 	if isDwarf64(c.linkctxt) {
 		size = 8
@@ -153,25 +153,25 @@
 	dsu.AddSymRef(c.arch, tds, ofs, objabi.R_DWARFSECREF, size)
 }
 
-func (c dwctxt2) Logf(format string, args ...interface{}) {
+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 dwctxt2) AddFileRef(s dwarf.Sym, f interface{}) {
+func (c dwctxt) AddFileRef(s dwarf.Sym, f interface{}) {
 	panic("should be used only in the compiler")
 }
 
-func (c dwctxt2) CurrentOffset(s dwarf.Sym) int64 {
+func (c dwctxt) CurrentOffset(s dwarf.Sym) int64 {
 	panic("should be used only in the compiler")
 }
 
-func (c dwctxt2) RecordDclReference(s dwarf.Sym, t dwarf.Sym, dclIdx int, inlIndex int) {
+func (c dwctxt) RecordDclReference(s dwarf.Sym, t dwarf.Sym, dclIdx int, inlIndex int) {
 	panic("should be used only in the compiler")
 }
 
-func (c dwctxt2) RecordChildDieOffsets(s dwarf.Sym, vars []*dwarf.Var, offsets []int32) {
+func (c dwctxt) RecordChildDieOffsets(s dwarf.Sym, vars []*dwarf.Var, offsets []int32) {
 	panic("should be used only in the compiler")
 }
 
@@ -207,11 +207,11 @@
 	return dsi.syms[1:]
 }
 
-// dwarfp2 stores the collected DWARF symbols created during
+// dwarfp stores the collected DWARF symbols created during
 // dwarf generation.
-var dwarfp2 []dwarfSecInfo
+var dwarfp []dwarfSecInfo
 
-func (d *dwctxt2) writeabbrev() dwarfSecInfo {
+func (d *dwctxt) writeabbrev() dwarfSecInfo {
 	abrvs := d.ldr.LookupOrCreateSym(".debug_abbrev", 0)
 	u := d.ldr.MakeSymbolUpdater(abrvs)
 	u.SetType(sym.SDWARFSECT)
@@ -269,7 +269,7 @@
 // The compiler does create nameless DWARF DIEs (ex: concrete subprogram
 // instance).
 // FIXME: it would be more efficient to bulk-allocate DIEs.
-func (d *dwctxt2) newdie(parent *dwarf.DWDie, abbrev int, name string, version int) *dwarf.DWDie {
+func (d *dwctxt) newdie(parent *dwarf.DWDie, abbrev int, name string, version int) *dwarf.DWDie {
 	die := new(dwarf.DWDie)
 	die.Abbrev = abbrev
 	die.Link = parent.Child
@@ -277,24 +277,37 @@
 
 	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) {
-		// Q: do we need version here? My understanding is that all these
-		// symbols should be version 0.
-		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(d.linkctxt.compUnits))
-			}
-			ds := d.ldr.LookupOrCreateSym(dwarf.InfoPrefix+name, version)
-			dsu := d.ldr.MakeSymbolUpdater(ds)
-			dsu.SetType(sym.SDWARFINFO)
-			d.ldr.SetAttrNotInSymbolTable(ds, true)
-			d.ldr.SetAttrReachable(ds, true)
-			die.Sym = dwSym(ds)
-			if abbrev >= dwarf.DW_ABRV_NULLTYPE && abbrev <= dwarf.DW_ABRV_TYPEDECL {
-				d.tmap[name] = ds
-			}
-		}
+	// Sanity check: all DIEs created in the linker should have a non-empty
+	// name and be version zero.
+	if name == "" || version != 0 {
+		panic("nameless or version non-zero DWARF DIE")
+	}
+
+	var st sym.SymKind
+	switch abbrev {
+	case dwarf.DW_ABRV_FUNCTYPEPARAM, dwarf.DW_ABRV_DOTDOTDOT, dwarf.DW_ABRV_STRUCTFIELD, dwarf.DW_ABRV_ARRAYRANGE:
+		// There are no relocations against these dies, and their names
+		// are not unique, so don't create a symbol.
+		return die
+	case dwarf.DW_ABRV_COMPUNIT, dwarf.DW_ABRV_COMPUNIT_TEXTLESS:
+		// Avoid collisions with "real" symbol names.
+		name = fmt.Sprintf(".pkg.%s.%d", name, len(d.linkctxt.compUnits))
+		st = sym.SDWARFCUINFO
+	case dwarf.DW_ABRV_VARIABLE:
+		st = sym.SDWARFVAR
+	default:
+		// Everything else is assigned a type of SDWARFTYPE. that
+		// this also includes loose ends such as STRUCT_FIELD.
+		st = sym.SDWARFTYPE
+	}
+	ds := d.ldr.LookupOrCreateSym(dwarf.InfoPrefix+name, version)
+	dsu := d.ldr.MakeSymbolUpdater(ds)
+	dsu.SetType(st)
+	d.ldr.SetAttrNotInSymbolTable(ds, true)
+	d.ldr.SetAttrReachable(ds, true)
+	die.Sym = dwSym(ds)
+	if abbrev >= dwarf.DW_ABRV_NULLTYPE && abbrev <= dwarf.DW_ABRV_TYPEDECL {
+		d.tmap[name] = ds
 	}
 
 	return die
@@ -316,7 +329,7 @@
 	return die
 }
 
-func (d *dwctxt2) walksymtypedef(symIdx loader.Sym) loader.Sym {
+func (d *dwctxt) walksymtypedef(symIdx loader.Sym) loader.Sym {
 
 	// We're being given the loader symbol for the type DIE, e.g.
 	// "go.info.type.uintptr". Map that first to the type symbol (e.g.
@@ -349,16 +362,13 @@
 	return nil
 }
 
-// Used to avoid string allocation when looking up dwarf symbols
-var prefixBuf = []byte(dwarf.InfoPrefix)
-
 // find looks up the loader symbol for the DWARF DIE generated for the
 // type with the specified name.
-func (d *dwctxt2) find(name string) loader.Sym {
+func (d *dwctxt) find(name string) loader.Sym {
 	return d.tmap[name]
 }
 
-func (d *dwctxt2) mustFind(name string) loader.Sym {
+func (d *dwctxt) mustFind(name string) loader.Sym {
 	r := d.find(name)
 	if r == 0 {
 		Exitf("dwarf find: cannot find %s", name)
@@ -366,7 +376,7 @@
 	return r
 }
 
-func (d *dwctxt2) adddwarfref(sb *loader.SymbolBuilder, t loader.Sym, size int) int64 {
+func (d *dwctxt) adddwarfref(sb *loader.SymbolBuilder, t loader.Sym, size int) int64 {
 	var result int64
 	switch size {
 	default:
@@ -377,14 +387,14 @@
 	return result
 }
 
-func (d *dwctxt2) newrefattr(die *dwarf.DWDie, attr uint16, ref loader.Sym) *dwarf.DWAttr {
+func (d *dwctxt) newrefattr(die *dwarf.DWDie, attr uint16, ref loader.Sym) *dwarf.DWAttr {
 	if ref == 0 {
 		return nil
 	}
 	return newattr(die, attr, dwarf.DW_CLS_REFERENCE, 0, dwSym(ref))
 }
 
-func (d *dwctxt2) dtolsym(s dwarf.Sym) loader.Sym {
+func (d *dwctxt) dtolsym(s dwarf.Sym) loader.Sym {
 	if s == nil {
 		return 0
 	}
@@ -392,7 +402,7 @@
 	return dws
 }
 
-func (d *dwctxt2) putdie(syms []loader.Sym, die *dwarf.DWDie) []loader.Sym {
+func (d *dwctxt) putdie(syms []loader.Sym, die *dwarf.DWDie) []loader.Sym {
 	s := d.dtolsym(die.Sym)
 	if s == 0 {
 		s = syms[len(syms)-1]
@@ -444,11 +454,11 @@
 
 // GDB doesn't like FORM_addr for AT_location, so emit a
 // location expression that evals to a const.
-func (d *dwctxt2) newabslocexprattr(die *dwarf.DWDie, addr int64, symIdx loader.Sym) {
+func (d *dwctxt) newabslocexprattr(die *dwarf.DWDie, addr int64, symIdx loader.Sym) {
 	newattr(die, dwarf.DW_AT_location, dwarf.DW_CLS_ADDRESS, addr, dwSym(symIdx))
 }
 
-func (d *dwctxt2) lookupOrDiag(n string) loader.Sym {
+func (d *dwctxt) lookupOrDiag(n string) loader.Sym {
 	symIdx := d.ldr.Lookup(n, 0)
 	if symIdx == 0 {
 		Exitf("dwarf: missing type: %s", n)
@@ -460,7 +470,7 @@
 	return symIdx
 }
 
-func (d *dwctxt2) dotypedef(parent *dwarf.DWDie, gotype loader.Sym, name string, def *dwarf.DWDie) *dwarf.DWDie {
+func (d *dwctxt) dotypedef(parent *dwarf.DWDie, gotype loader.Sym, name string, def *dwarf.DWDie) *dwarf.DWDie {
 	// Only emit typedefs for real names.
 	if strings.HasPrefix(name, "map[") {
 		return nil
@@ -483,7 +493,7 @@
 	// to be an anonymous symbol (we want this for perf reasons).
 	tds := d.ldr.CreateExtSym("", 0)
 	tdsu := d.ldr.MakeSymbolUpdater(tds)
-	tdsu.SetType(sym.SDWARFINFO)
+	tdsu.SetType(sym.SDWARFTYPE)
 	def.Sym = dwSym(tds)
 	d.ldr.SetAttrNotInSymbolTable(tds, true)
 	d.ldr.SetAttrReachable(tds, true)
@@ -500,7 +510,7 @@
 }
 
 // Define gotype, for composite ones recurse into constituents.
-func (d *dwctxt2) defgotype(gotype loader.Sym) loader.Sym {
+func (d *dwctxt) defgotype(gotype loader.Sym) loader.Sym {
 	if gotype == 0 {
 		return d.mustFind("<unspecified>")
 	}
@@ -527,7 +537,7 @@
 	return loader.Sym(gtdwSym.Sym.(dwSym))
 }
 
-func (d *dwctxt2) newtype(gotype loader.Sym) *dwarf.DWDie {
+func (d *dwctxt) newtype(gotype loader.Sym) *dwarf.DWDie {
 	sn := d.ldr.SymName(gotype)
 	name := sn[5:] // could also decode from Type.string
 	tdata := d.ldr.Data(gotype)
@@ -717,12 +727,12 @@
 	return die
 }
 
-func (d *dwctxt2) nameFromDIESym(dwtypeDIESym loader.Sym) string {
+func (d *dwctxt) nameFromDIESym(dwtypeDIESym loader.Sym) string {
 	sn := d.ldr.SymName(dwtypeDIESym)
 	return sn[len(dwarf.InfoPrefix):]
 }
 
-func (d *dwctxt2) defptrto(dwtype loader.Sym) loader.Sym {
+func (d *dwctxt) defptrto(dwtype loader.Sym) loader.Sym {
 
 	// FIXME: it would be nice if the compiler attached an aux symbol
 	// ref from the element type to the pointer type -- it would be
@@ -756,7 +766,7 @@
 // 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 (d *dwctxt2) copychildrenexcept(ctxt *Link, dst *dwarf.DWDie, src *dwarf.DWDie, except *dwarf.DWDie) {
+func (d *dwctxt) 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
@@ -771,13 +781,13 @@
 	reverselist(&dst.Child)
 }
 
-func (d *dwctxt2) copychildren(ctxt *Link, dst *dwarf.DWDie, src *dwarf.DWDie) {
+func (d *dwctxt) copychildren(ctxt *Link, dst *dwarf.DWDie, src *dwarf.DWDie) {
 	d.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 (d *dwctxt2) substitutetype(structdie *dwarf.DWDie, field string, dwtype loader.Sym) {
+func (d *dwctxt) substitutetype(structdie *dwarf.DWDie, field string, dwtype loader.Sym) {
 	child := findchild(structdie, field)
 	if child == nil {
 		Exitf("dwarf substitutetype: %s does not have member %s",
@@ -793,7 +803,7 @@
 	}
 }
 
-func (d *dwctxt2) findprotodie(ctxt *Link, name string) *dwarf.DWDie {
+func (d *dwctxt) findprotodie(ctxt *Link, name string) *dwarf.DWDie {
 	die, ok := prototypedies[name]
 	if ok && die == nil {
 		d.defgotype(d.lookupOrDiag(name))
@@ -805,7 +815,7 @@
 	return die
 }
 
-func (d *dwctxt2) synthesizestringtypes(ctxt *Link, die *dwarf.DWDie) {
+func (d *dwctxt) synthesizestringtypes(ctxt *Link, die *dwarf.DWDie) {
 	prototype := walktypedef(d.findprotodie(ctxt, "type.runtime.stringStructDWARF"))
 	if prototype == nil {
 		return
@@ -819,7 +829,7 @@
 	}
 }
 
-func (d *dwctxt2) synthesizeslicetypes(ctxt *Link, die *dwarf.DWDie) {
+func (d *dwctxt) synthesizeslicetypes(ctxt *Link, die *dwarf.DWDie) {
 	prototype := walktypedef(d.findprotodie(ctxt, "type.runtime.slice"))
 	if prototype == nil {
 		return
@@ -849,11 +859,11 @@
 	BucketSize = 8
 )
 
-func (d *dwctxt2) mkinternaltype(ctxt *Link, abbrev int, typename, keyname, valname string, f func(*dwarf.DWDie)) loader.Sym {
+func (d *dwctxt) mkinternaltype(ctxt *Link, abbrev int, typename, keyname, valname string, f func(*dwarf.DWDie)) loader.Sym {
 	name := mkinternaltypename(typename, keyname, valname)
 	symname := dwarf.InfoPrefix + name
 	s := d.ldr.Lookup(symname, 0)
-	if s != 0 && d.ldr.SymType(s) == sym.SDWARFINFO {
+	if s != 0 && d.ldr.SymType(s) == sym.SDWARFTYPE {
 		return s
 	}
 	die := d.newdie(&dwtypes, abbrev, name, 0)
@@ -861,7 +871,7 @@
 	return d.dtolsym(die.Sym)
 }
 
-func (d *dwctxt2) synthesizemaptypes(ctxt *Link, die *dwarf.DWDie) {
+func (d *dwctxt) synthesizemaptypes(ctxt *Link, die *dwarf.DWDie) {
 	hash := walktypedef(d.findprotodie(ctxt, "type.runtime.hmap"))
 	bucket := walktypedef(d.findprotodie(ctxt, "type.runtime.bmap"))
 
@@ -957,7 +967,7 @@
 	}
 }
 
-func (d *dwctxt2) synthesizechantypes(ctxt *Link, die *dwarf.DWDie) {
+func (d *dwctxt) synthesizechantypes(ctxt *Link, die *dwarf.DWDie) {
 	sudog := walktypedef(d.findprotodie(ctxt, "type.runtime.sudog"))
 	waitq := walktypedef(d.findprotodie(ctxt, "type.runtime.waitq"))
 	hchan := walktypedef(d.findprotodie(ctxt, "type.runtime.hchan"))
@@ -1004,7 +1014,7 @@
 	}
 }
 
-func (d *dwctxt2) dwarfDefineGlobal(ctxt *Link, symIdx loader.Sym, str string, v int64, gotype loader.Sym) {
+func (d *dwctxt) dwarfDefineGlobal(ctxt *Link, symIdx loader.Sym, str string, v int64, gotype loader.Sym) {
 	// 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
@@ -1025,7 +1035,7 @@
 
 // createUnitLength creates the initial length field with value v and update
 // offset of unit_length if needed.
-func (d *dwctxt2) createUnitLength(su *loader.SymbolBuilder, v uint64) {
+func (d *dwctxt) createUnitLength(su *loader.SymbolBuilder, v uint64) {
 	if isDwarf64(d.linkctxt) {
 		su.AddUint32(d.arch, 0xFFFFFFFF)
 	}
@@ -1033,7 +1043,7 @@
 }
 
 // addDwarfAddrField adds a DWARF field in DWARF 64bits or 32bits.
-func (d *dwctxt2) addDwarfAddrField(sb *loader.SymbolBuilder, v uint64) {
+func (d *dwctxt) addDwarfAddrField(sb *loader.SymbolBuilder, v uint64) {
 	if isDwarf64(d.linkctxt) {
 		sb.AddUint(d.arch, v)
 	} else {
@@ -1042,7 +1052,7 @@
 }
 
 // addDwarfAddrRef adds a DWARF pointer in DWARF 64bits or 32bits.
-func (d *dwctxt2) addDwarfAddrRef(sb *loader.SymbolBuilder, t loader.Sym) {
+func (d *dwctxt) addDwarfAddrRef(sb *loader.SymbolBuilder, t loader.Sym) {
 	if isDwarf64(d.linkctxt) {
 		d.adddwarfref(sb, t, 8)
 	} else {
@@ -1051,9 +1061,9 @@
 }
 
 // calcCompUnitRanges calculates the PC ranges of the compilation units.
-func (d *dwctxt2) calcCompUnitRanges() {
+func (d *dwctxt) calcCompUnitRanges() {
 	var prevUnit *sym.CompilationUnit
-	for _, s := range d.linkctxt.Textp2 {
+	for _, s := range d.linkctxt.Textp {
 		sym := loader.Sym(s)
 
 		fi := d.ldr.FuncInfo(sym)
@@ -1076,7 +1086,7 @@
 		// only create boundaries between symbols from
 		// different units.
 		sval := d.ldr.SymValue(sym)
-		u0val := d.ldr.SymValue(loader.Sym(unit.Textp2[0]))
+		u0val := d.ldr.SymValue(loader.Sym(unit.Textp[0]))
 		if prevUnit != unit {
 			unit.PCs = append(unit.PCs, dwarf.Range{Start: sval - u0val})
 			prevUnit = unit
@@ -1122,10 +1132,11 @@
 	return "."
 }
 
-func (d *dwctxt2) importInfoSymbol(ctxt *Link, dsym loader.Sym) {
+func (d *dwctxt) importInfoSymbol(dsym loader.Sym) {
 	d.ldr.SetAttrReachable(dsym, true)
 	d.ldr.SetAttrNotInSymbolTable(dsym, true)
-	if d.ldr.SymType(dsym) != sym.SDWARFINFO {
+	dst := d.ldr.SymType(dsym)
+	if dst != sym.SDWARFCONST && dst != sym.SDWARFABSFCN {
 		log.Fatalf("error: DWARF info sym %d/%s with incorrect type %s", dsym, d.ldr.SymName(dsym), d.ldr.SymType(dsym).String())
 	}
 	relocs := d.ldr.Relocs(dsym)
@@ -1157,11 +1168,7 @@
 	return expandGoroot(fname)
 }
 
-func expandFileSym(l *loader.Loader, fsym loader.Sym) string {
-	return expandFile(l.SymName(fsym))
-}
-
-func (d *dwctxt2) writelines(unit *sym.CompilationUnit, ls loader.Sym) {
+func (d *dwctxt) writelines(unit *sym.CompilationUnit, ls loader.Sym) {
 
 	is_stmt := uint8(1) // initially = recommended default_is_stmt = 1, tracks is_stmt toggles.
 
@@ -1237,7 +1244,7 @@
 
 	// Output the state machine for each function remaining.
 	var lastAddr int64
-	for _, s := range unit.Textp2 {
+	for _, s := range unit.Textp {
 		fnSym := loader.Sym(s)
 
 		// Set the PC.
@@ -1293,7 +1300,7 @@
 }
 
 // writepcranges generates the DW_AT_ranges table for compilation unit cu.
-func (d *dwctxt2) writepcranges(unit *sym.CompilationUnit, base loader.Sym, pcs []dwarf.Range, ranges loader.Sym) {
+func (d *dwctxt) writepcranges(unit *sym.CompilationUnit, base loader.Sym, pcs []dwarf.Range, ranges loader.Sym) {
 
 	rsu := d.ldr.MakeSymbolUpdater(ranges)
 	rDwSym := dwSym(ranges)
@@ -1338,7 +1345,7 @@
 	return b
 }
 
-func (d *dwctxt2) writeframes() dwarfSecInfo {
+func (d *dwctxt) writeframes() dwarfSecInfo {
 	fs := d.ldr.LookupOrCreateSym(".debug_frame", 0)
 	fsd := dwSym(fs)
 	fsu := d.ldr.MakeSymbolUpdater(fs)
@@ -1400,7 +1407,7 @@
 
 	var deltaBuf []byte
 	pcsp := obj.NewPCIter(uint32(d.arch.MinLC))
-	for _, s := range d.linkctxt.Textp2 {
+	for _, s := range d.linkctxt.Textp {
 		fn := loader.Sym(s)
 		fi := d.ldr.FuncInfo(fn)
 		if !fi.Valid() {
@@ -1507,11 +1514,11 @@
 	return syms
 }
 
-func (d *dwctxt2) writeinfo(units []*sym.CompilationUnit, abbrevsym loader.Sym, pubNames, pubTypes *pubWriter2) dwarfSecInfo {
+func (d *dwctxt) writeinfo(units []*sym.CompilationUnit, abbrevsym loader.Sym, pubNames, pubTypes *pubWriter) dwarfSecInfo {
 
 	infosec := d.ldr.LookupOrCreateSym(".debug_info", 0)
 	disu := d.ldr.MakeSymbolUpdater(infosec)
-	disu.SetType(sym.SDWARFINFO)
+	disu.SetType(sym.SDWARFCUINFO)
 	d.ldr.SetAttrReachable(infosec, true)
 	syms := []loader.Sym{infosec}
 
@@ -1520,7 +1527,7 @@
 		s := d.dtolsym(compunit.Sym)
 		su := d.ldr.MakeSymbolUpdater(s)
 
-		if len(u.Textp2) == 0 && u.DWInfo.Child == nil {
+		if len(u.Textp) == 0 && u.DWInfo.Child == nil {
 			continue
 		}
 
@@ -1543,10 +1550,10 @@
 		dwarf.PutAttrs(d, ds, compunit.Abbrev, compunit.Attr)
 
 		cu := []loader.Sym{s}
-		cu = appendSyms(cu, u.AbsFnDIEs2)
-		cu = appendSyms(cu, u.FuncDIEs2)
-		if u.Consts2 != 0 {
-			cu = append(cu, loader.Sym(u.Consts2))
+		cu = appendSyms(cu, u.AbsFnDIEs)
+		cu = appendSyms(cu, u.FuncDIEs)
+		if u.Consts != 0 {
+			cu = append(cu, loader.Sym(u.Consts))
 		}
 		var cusize int64
 		for _, child := range cu {
@@ -1600,8 +1607,8 @@
  *  because we need die->offs and infoo/infosize;
  */
 
-type pubWriter2 struct {
-	d     *dwctxt2
+type pubWriter struct {
+	d     *dwctxt
 	s     loader.Sym
 	su    *loader.SymbolBuilder
 	sname string
@@ -1610,14 +1617,14 @@
 	culengthOff  int64
 }
 
-func newPubWriter2(d *dwctxt2, sname string) *pubWriter2 {
+func newPubWriter(d *dwctxt, sname string) *pubWriter {
 	s := d.ldr.LookupOrCreateSym(sname, 0)
 	u := d.ldr.MakeSymbolUpdater(s)
 	u.SetType(sym.SDWARFSECT)
-	return &pubWriter2{d: d, s: s, su: u, sname: sname}
+	return &pubWriter{d: d, s: s, su: u, sname: sname}
 }
 
-func (pw *pubWriter2) beginCompUnit(compunit *dwarf.DWDie) {
+func (pw *pubWriter) beginCompUnit(compunit *dwarf.DWDie) {
 	pw.sectionstart = pw.su.Size()
 
 	// Write .debug_pubnames/types	Header (sec 6.1.1)
@@ -1628,7 +1635,7 @@
 	pw.d.addDwarfAddrField(pw.su, uint64(0)) // debug_info_length, will be filled in later.
 }
 
-func (pw *pubWriter2) add(die *dwarf.DWDie, offset int64) {
+func (pw *pubWriter) add(die *dwarf.DWDie, offset int64) {
 	dwa := getattr(die, dwarf.DW_AT_name)
 	name := dwa.Data.(string)
 	if pw.d.dtolsym(die.Sym) == 0 {
@@ -1638,7 +1645,7 @@
 	pw.su.Addstring(name)
 }
 
-func (pw *pubWriter2) endCompUnit(compunit *dwarf.DWDie, culength uint32) {
+func (pw *pubWriter) endCompUnit(compunit *dwarf.DWDie, culength uint32) {
 	pw.d.addDwarfAddrField(pw.su, 0) // Null offset
 
 	// On AIX, save the current size of this compilation unit.
@@ -1668,7 +1675,7 @@
 	return die.Abbrev >= dwarf.DW_ABRV_NULLTYPE
 }
 
-func (d *dwctxt2) writegdbscript() dwarfSecInfo {
+func (d *dwctxt) writegdbscript() dwarfSecInfo {
 	// TODO (aix): make it available
 	if d.linkctxt.HeadType == objabi.Haix {
 		return dwarfSecInfo{}
@@ -1732,7 +1739,7 @@
 
 // mkBuiltinType populates the dwctxt2 sym lookup maps for the
 // newly created builtin type DIE 'typeDie'.
-func (d *dwctxt2) mkBuiltinType(ctxt *Link, abrv int, tname string) *dwarf.DWDie {
+func (d *dwctxt) mkBuiltinType(ctxt *Link, abrv int, tname string) *dwarf.DWDie {
 	// create type DIE
 	die := d.newdie(&dwtypes, abrv, tname, 0)
 
@@ -1749,6 +1756,76 @@
 	return die
 }
 
+// dwarfVisitFunction takes a function (text) symbol and processes the
+// subprogram DIE for the function and picks up any other DIEs
+// (absfns, types) that it references.
+func (d *dwctxt) dwarfVisitFunction(fnSym loader.Sym, unit *sym.CompilationUnit) {
+	// The DWARF subprogram DIE symbol is listed as an aux sym
+	// of the text (fcn) symbol, so ask the loader to retrieve it,
+	// as well as the associated range symbol.
+	infosym, _, rangesym, _ := d.ldr.GetFuncDwarfAuxSyms(fnSym)
+	if infosym == 0 {
+		return
+	}
+	d.ldr.SetAttrNotInSymbolTable(infosym, true)
+	d.ldr.SetAttrReachable(infosym, true)
+	unit.FuncDIEs = append(unit.FuncDIEs, sym.LoaderSym(infosym))
+	if rangesym != 0 {
+		rs := len(d.ldr.Data(rangesym))
+		d.ldr.SetAttrNotInSymbolTable(rangesym, true)
+		d.ldr.SetAttrReachable(rangesym, true)
+		if d.linkctxt.IsAIX() {
+			addDwsectCUSize(".debug_ranges", unit.Lib.Pkg, uint64(rs))
+		}
+		unit.RangeSyms = append(unit.RangeSyms, sym.LoaderSym(rangesym))
+	}
+
+	// Walk the relocations of the subprogram DIE symbol to discover
+	// references to abstract function DIEs, Go type DIES, and
+	// (via R_USETYPE relocs) types that were originally assigned to
+	// locals/params but were optimized away.
+	drelocs := d.ldr.Relocs(infosym)
+	for ri := 0; ri < drelocs.Count(); ri++ {
+		r := drelocs.At2(ri)
+		// Look for "use type" relocs.
+		if r.Type() == objabi.R_USETYPE {
+			d.defgotype(r.Sym())
+			continue
+		}
+		if r.Type() != objabi.R_DWARFSECREF {
+			continue
+		}
+
+		rsym := r.Sym()
+		rst := d.ldr.SymType(rsym)
+
+		// Look for abstract function references.
+		if rst == sym.SDWARFABSFCN {
+			if !d.ldr.AttrOnList(rsym) {
+				// abstract function
+				d.ldr.SetAttrOnList(rsym, true)
+				unit.AbsFnDIEs = append(unit.AbsFnDIEs, sym.LoaderSym(rsym))
+				d.importInfoSymbol(rsym)
+			}
+			continue
+		}
+
+		// Look for type references.
+		if rst != sym.SDWARFTYPE && rst != sym.Sxxx {
+			continue
+		}
+		if _, ok := d.rtmap[rsym]; ok {
+			// type already generated
+			continue
+		}
+
+		rsn := d.ldr.SymName(rsym)
+		tn := rsn[len(dwarf.InfoPrefix):]
+		ts := d.ldr.Lookup("type."+tn, 0)
+		d.defgotype(ts)
+	}
+}
+
 // 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
@@ -1761,7 +1838,7 @@
 		return
 	}
 
-	d := newdwctxt2(ctxt, true)
+	d := newdwctxt(ctxt, true)
 
 	if ctxt.HeadType == objabi.Haix {
 		// Initial map used to store package size for each DWARF section.
@@ -1822,8 +1899,8 @@
 		for _, unit := range lib.Units {
 			// We drop the constants into the first CU.
 			if consts != 0 {
-				unit.Consts2 = sym.LoaderSym(consts)
-				d.importInfoSymbol(ctxt, consts)
+				unit.Consts = sym.LoaderSym(consts)
+				d.importInfoSymbol(consts)
 				consts = 0
 			}
 			ctxt.compUnits = append(ctxt.compUnits, unit)
@@ -1833,7 +1910,11 @@
 				ctxt.runtimeCU = unit
 			}
 
-			unit.DWInfo = d.newdie(&dwroot, dwarf.DW_ABRV_COMPUNIT, unit.Lib.Pkg, 0)
+			cuabrv := dwarf.DW_ABRV_COMPUNIT
+			if len(unit.Textp) == 0 {
+				cuabrv = dwarf.DW_ABRV_COMPUNIT_TEXTLESS
+			}
+			unit.DWInfo = d.newdie(&dwroot, cuabrv, 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()
@@ -1869,60 +1950,12 @@
 			}
 			newattr(unit.DWInfo, dwarf.DW_AT_go_package_name, dwarf.DW_CLS_STRING, int64(len(pkgname)), pkgname)
 
-			if len(unit.Textp2) == 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.Textp2 { // textp2 has been dead-code-eliminated already.
-				fnSym := loader.Sym(s)
-				infosym, _, rangesym, _ := d.ldr.GetFuncDwarfAuxSyms(fnSym)
-				if infosym == 0 {
-					continue
-				}
-				d.ldr.SetAttrNotInSymbolTable(infosym, true)
-				d.ldr.SetAttrReachable(infosym, true)
-
-				unit.FuncDIEs2 = append(unit.FuncDIEs2, sym.LoaderSym(infosym))
-				if rangesym != 0 {
-					rs := len(d.ldr.Data(rangesym))
-					d.ldr.SetAttrNotInSymbolTable(rangesym, true)
-					d.ldr.SetAttrReachable(rangesym, true)
-					if ctxt.HeadType == objabi.Haix {
-						addDwsectCUSize(".debug_ranges", unit.Lib.Pkg, uint64(rs))
-					}
-					unit.RangeSyms2 = append(unit.RangeSyms2, sym.LoaderSym(rangesym))
-				}
-
-				drelocs := d.ldr.Relocs(infosym)
-				for ri := 0; ri < drelocs.Count(); ri++ {
-					r := drelocs.At2(ri)
-					if r.Type() == objabi.R_DWARFSECREF {
-						rsym := r.Sym()
-						rsn := d.ldr.SymName(rsym)
-						if len(rsn) == 0 {
-							continue
-						}
-						// NB: there should be a better way to do this that doesn't involve materializing the symbol name and doing string prefix+suffix checks.
-						if strings.HasPrefix(rsn, dwarf.InfoPrefix) && strings.HasSuffix(rsn, dwarf.AbstractFuncSuffix) && !d.ldr.AttrOnList(rsym) {
-							// abstract function
-							d.ldr.SetAttrOnList(rsym, true)
-							unit.AbsFnDIEs2 = append(unit.AbsFnDIEs2, sym.LoaderSym(rsym))
-							d.importInfoSymbol(ctxt, rsym)
-							continue
-						}
-						if _, ok := d.rtmap[rsym]; ok {
-							// type already generated
-							continue
-						}
-						tn := rsn[len(dwarf.InfoPrefix):]
-						ts := d.ldr.Lookup("type."+tn, 0)
-						d.defgotype(ts)
-					}
-				}
+			// Scan all functions in this compilation unit, create
+			// DIEs for all referenced types, find all referenced
+			// abstract functions, visit range symbols. Note that
+			// Textp has been dead-code-eliminated already.
+			for _, s := range unit.Textp {
+				d.dwarfVisitFunction(loader.Sym(s), unit)
 			}
 		}
 	}
@@ -1971,26 +2004,6 @@
 		d.dwarfDefineGlobal(ctxt, idx, sn, sv, gt)
 	}
 
-	// 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.LoaderSym{unit.AbsFnDIEs2, unit.FuncDIEs2}
-			for _, list := range lists {
-				for _, s := range list {
-					symIdx := loader.Sym(s)
-					relocs := d.ldr.Relocs(symIdx)
-					for i := 0; i < relocs.Count(); i++ {
-						r := relocs.At2(i)
-						if r.Type() == objabi.R_USETYPE {
-							d.defgotype(r.Sym())
-						}
-					}
-				}
-			}
-		}
-	}
-
 	d.synthesizestringtypes(ctxt, dwtypes.Child)
 	d.synthesizeslicetypes(ctxt, dwtypes.Child)
 	d.synthesizemaptypes(ctxt, dwtypes.Child)
@@ -2009,7 +2022,7 @@
 	if !dwarfEnabled(ctxt) {
 		return
 	}
-	d := &dwctxt2{
+	d := &dwctxt{
 		linkctxt: ctxt,
 		ldr:      ctxt.loader,
 		arch:     ctxt.Arch,
@@ -2017,9 +2030,9 @@
 	d.dwarfGenerateDebugSyms()
 }
 
-func (d *dwctxt2) dwarfGenerateDebugSyms() {
+func (d *dwctxt) dwarfGenerateDebugSyms() {
 	abbrevSec := d.writeabbrev()
-	dwarfp2 = append(dwarfp2, abbrevSec)
+	dwarfp = append(dwarfp, abbrevSec)
 
 	d.calcCompUnitRanges()
 	sort.Sort(compilationUnitByStartPC(d.linkctxt.compUnits))
@@ -2029,7 +2042,7 @@
 	dlu := d.ldr.MakeSymbolUpdater(debugLine)
 	dlu.SetType(sym.SDWARFSECT)
 	d.ldr.SetAttrReachable(debugLine, true)
-	dwarfp2 = append(dwarfp2, dwarfSecInfo{syms: []loader.Sym{debugLine}})
+	dwarfp = append(dwarfp, dwarfSecInfo{syms: []loader.Sym{debugLine}})
 
 	debugRanges := d.ldr.LookupOrCreateSym(".debug_ranges", 0)
 	dru := d.ldr.MakeSymbolUpdater(debugRanges)
@@ -2043,7 +2056,7 @@
 			continue
 		}
 		d.writelines(u, debugLine)
-		base := loader.Sym(u.Textp2[0])
+		base := loader.Sym(u.Textp[0])
 		d.writepcranges(u, base, u.PCs, debugRanges)
 	}
 
@@ -2053,39 +2066,39 @@
 	reversetree(&dwtypes.Child)
 	movetomodule(d.linkctxt, &dwtypes)
 
-	pubNames := newPubWriter2(d, ".debug_pubnames")
-	pubTypes := newPubWriter2(d, ".debug_pubtypes")
+	pubNames := newPubWriter(d, ".debug_pubnames")
+	pubTypes := newPubWriter(d, ".debug_pubtypes")
 
 	infoSec := d.writeinfo(d.linkctxt.compUnits, abbrevSec.secSym(), pubNames, pubTypes)
 
 	framesSec := d.writeframes()
-	dwarfp2 = append(dwarfp2, framesSec)
-	dwarfp2 = append(dwarfp2, dwarfSecInfo{syms: []loader.Sym{pubNames.s}})
-	dwarfp2 = append(dwarfp2, dwarfSecInfo{syms: []loader.Sym{pubTypes.s}})
+	dwarfp = append(dwarfp, framesSec)
+	dwarfp = append(dwarfp, dwarfSecInfo{syms: []loader.Sym{pubNames.s}})
+	dwarfp = append(dwarfp, dwarfSecInfo{syms: []loader.Sym{pubTypes.s}})
 	gdbScriptSec := d.writegdbscript()
 	if gdbScriptSec.secSym() != 0 {
-		dwarfp2 = append(dwarfp2, gdbScriptSec)
+		dwarfp = append(dwarfp, gdbScriptSec)
 	}
-	dwarfp2 = append(dwarfp2, infoSec)
+	dwarfp = append(dwarfp, infoSec)
 	locSec := d.collectlocs(d.linkctxt.compUnits)
 	if locSec.secSym() != 0 {
-		dwarfp2 = append(dwarfp2, locSec)
+		dwarfp = append(dwarfp, locSec)
 	}
 
 	rsyms := []loader.Sym{debugRanges}
 	for _, unit := range d.linkctxt.compUnits {
-		for _, s := range unit.RangeSyms2 {
+		for _, s := range unit.RangeSyms {
 			rsyms = append(rsyms, loader.Sym(s))
 		}
 	}
-	dwarfp2 = append(dwarfp2, dwarfSecInfo{syms: rsyms})
+	dwarfp = append(dwarfp, dwarfSecInfo{syms: rsyms})
 }
 
-func (d *dwctxt2) collectlocs(units []*sym.CompilationUnit) dwarfSecInfo {
+func (d *dwctxt) collectlocs(units []*sym.CompilationUnit) dwarfSecInfo {
 	empty := true
 	syms := []loader.Sym{}
 	for _, u := range units {
-		for _, fn := range u.FuncDIEs2 {
+		for _, fn := range u.FuncDIEs {
 			relocs := d.ldr.Relocs(loader.Sym(fn))
 			for i := 0; i < relocs.Count(); i++ {
 				reloc := relocs.At2(i)
@@ -2117,31 +2130,11 @@
 	return dwarfSecInfo{syms: append([]loader.Sym{locsym}, syms...)}
 }
 
-/*
- *  Elf.
- */
-func (d *dwctxt2) dwarfaddshstrings(ctxt *Link, shstrtab loader.Sym) {
-	panic("not yet implemented")
-}
-
-// Add section symbols for DWARF debug info.  This is called before
-// dwarfaddelfheaders.
-func (d *dwctxt2) dwarfaddelfsectionsyms(ctxt *Link) {
-	panic("not yet implemented")
-}
-
-// 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 (d *dwctxt2) dwarfcompress(ctxt *Link) {
-	panic("not yet implemented")
-}
-
 // 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 (d *dwctxt2) getPkgFromCUSym(s loader.Sym) string {
+func (d *dwctxt) getPkgFromCUSym(s loader.Sym) string {
 	return strings.TrimPrefix(d.ldr.SymName(s), dwarf.InfoPrefix+".pkg.")
 }
 
@@ -2164,3 +2157,19 @@
 func addDwsectCUSize(sname string, pkgname string, size uint64) {
 	dwsectCUSize[sname+"."+pkgname] += size
 }
+
+func dwarfaddelfsectionsyms(ctxt *Link) {
+	if *FlagW { // disable dwarf
+		return
+	}
+	if ctxt.LinkMode != LinkExternal {
+		return
+	}
+
+	ldr := ctxt.loader
+	for _, si := range dwarfp {
+		s := si.secSym()
+		sect := ldr.SymSect(si.secSym())
+		putelfsectionsym(ctxt, ctxt.Out, s, sect.Elfsect.(*ElfShdr).shnum)
+	}
+}
diff --git a/src/cmd/link/internal/ld/dwarf2.go b/src/cmd/link/internal/ld/dwarf2.go
index 79abccf..0c1a0ca 100644
--- a/src/cmd/link/internal/ld/dwarf2.go
+++ b/src/cmd/link/internal/ld/dwarf2.go
@@ -24,28 +24,6 @@
 	return ctxt.HeadType == objabi.Haix
 }
 
-// dwarfSecInfo2 is a replica of the dwarfSecInfo struct but with
-// *sym.Symbol content instead of loader.Sym content.
-type dwarfSecInfo2 struct {
-	syms []*sym.Symbol
-}
-
-func (dsi *dwarfSecInfo2) secSym() *sym.Symbol {
-	if len(dsi.syms) == 0 {
-		return nil
-	}
-	return dsi.syms[0]
-}
-
-func (dsi *dwarfSecInfo2) subSyms() []*sym.Symbol {
-	if len(dsi.syms) == 0 {
-		return []*sym.Symbol{}
-	}
-	return dsi.syms[1:]
-}
-
-var dwarfp []dwarfSecInfo2
-
 /*
  *  Elf.
  */
@@ -65,34 +43,6 @@
 	}
 }
 
-// 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, ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
-	s = ctxt.Syms.Lookup(".debug_abbrev", 0)
-	putelfsectionsym(ctxt, ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
-	s = ctxt.Syms.Lookup(".debug_line", 0)
-	putelfsectionsym(ctxt, ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
-	s = ctxt.Syms.Lookup(".debug_frame", 0)
-	putelfsectionsym(ctxt, ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
-	s = ctxt.Syms.Lookup(".debug_loc", 0)
-	if s.Sect != nil {
-		putelfsectionsym(ctxt, ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
-	}
-	s = ctxt.Syms.Lookup(".debug_ranges", 0)
-	if s.Sect != nil {
-		putelfsectionsym(ctxt, 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.
@@ -111,10 +61,10 @@
 
 	var compressedCount int
 	resChannel := make(chan compressedSect)
-	for i := range dwarfp2 {
+	for i := range dwarfp {
 		go func(resIndex int, syms []loader.Sym) {
 			resChannel <- compressedSect{resIndex, compressSyms(ctxt, syms), syms}
-		}(compressedCount, dwarfp2[i].syms)
+		}(compressedCount, dwarfp[i].syms)
 		compressedCount++
 	}
 	res := make([]compressedSect, compressedCount)
@@ -153,14 +103,14 @@
 			}
 		}
 	}
-	dwarfp2 = newDwarfp
+	dwarfp = newDwarfp
 
 	// 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 _, si := range dwarfp2 {
+	for _, si := range dwarfp {
 		for _, s := range si.syms {
 			ldr.SetSymValue(s, int64(pos))
 			sect := ldr.SymSect(s)
@@ -187,11 +137,11 @@
 
 func (v compilationUnitByStartPC) Less(i, j int) bool {
 	switch {
-	case len(v[i].Textp2) == 0 && len(v[j].Textp2) == 0:
+	case len(v[i].Textp) == 0 && len(v[j].Textp) == 0:
 		return v[i].Lib.Pkg < v[j].Lib.Pkg
-	case len(v[i].Textp2) != 0 && len(v[j].Textp2) == 0:
+	case len(v[i].Textp) != 0 && len(v[j].Textp) == 0:
 		return true
-	case len(v[i].Textp2) == 0 && len(v[j].Textp2) != 0:
+	case len(v[i].Textp) == 0 && len(v[j].Textp) != 0:
 		return false
 	default:
 		return v[i].PCs[0].Start < v[j].PCs[0].Start
diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go
index 78298be..b100d07 100644
--- a/src/cmd/link/internal/ld/elf.go
+++ b/src/cmd/link/internal/ld/elf.go
@@ -12,7 +12,6 @@
 	"crypto/sha1"
 	"encoding/binary"
 	"encoding/hex"
-	"io"
 	"path/filepath"
 	"sort"
 	"strings"
@@ -628,7 +627,7 @@
 	return uint32(ehdr.shnum) * ELF32SHDRSIZE
 }
 
-func elfsetstring2(ctxt *Link, s loader.Sym, str string, off int) {
+func elfsetstring(ctxt *Link, s loader.Sym, str string, off int) {
 	if nelfstr >= len(elfstr) {
 		ctxt.Errorf(s, "too many elf strings")
 		errorexit()
@@ -743,7 +742,11 @@
 	return h
 }
 
-func elfWriteDynEnt(arch *sys.Arch, s *sym.Symbol, tag int, val uint64) {
+func elfWriteDynEntSym(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym) {
+	Elfwritedynentsymplus(ctxt, s, tag, t, 0)
+}
+
+func Elfwritedynent(arch *sys.Arch, s *loader.SymbolBuilder, tag int, val uint64) {
 	if elf64 {
 		s.AddUint64(arch, uint64(tag))
 		s.AddUint64(arch, val)
@@ -753,44 +756,11 @@
 	}
 }
 
-func elfWriteDynEntSym2(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym) {
-	Elfwritedynentsymplus2(ctxt, s, tag, t, 0)
+func elfwritedynentsym(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym) {
+	Elfwritedynentsymplus(ctxt, s, tag, t, 0)
 }
 
-func Elfwritedynentsymplus(arch *sys.Arch, s *sym.Symbol, tag int, t *sym.Symbol, add int64) {
-	if elf64 {
-		s.AddUint64(arch, uint64(tag))
-	} else {
-		s.AddUint32(arch, uint32(tag))
-	}
-	s.AddAddrPlus(arch, t, add)
-}
-
-func elfWriteDynEntSymSize(arch *sys.Arch, s *sym.Symbol, tag int, t *sym.Symbol) {
-	if elf64 {
-		s.AddUint64(arch, uint64(tag))
-	} else {
-		s.AddUint32(arch, uint32(tag))
-	}
-	s.AddSize(arch, t)
-}
-
-// temporary
-func Elfwritedynent2(arch *sys.Arch, s *loader.SymbolBuilder, tag int, val uint64) {
-	if elf64 {
-		s.AddUint64(arch, uint64(tag))
-		s.AddUint64(arch, val)
-	} else {
-		s.AddUint32(arch, uint32(tag))
-		s.AddUint32(arch, uint32(val))
-	}
-}
-
-func elfwritedynentsym2(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym) {
-	Elfwritedynentsymplus2(ctxt, s, tag, t, 0)
-}
-
-func Elfwritedynentsymplus2(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym, add int64) {
+func Elfwritedynentsymplus(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym, add int64) {
 	if elf64 {
 		s.AddUint64(ctxt.Arch, uint64(tag))
 	} else {
@@ -799,7 +769,7 @@
 	s.AddAddrPlus(ctxt.Arch, t, add)
 }
 
-func elfwritedynentsymsize2(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym) {
+func elfwritedynentsymsize(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym) {
 	if elf64 {
 		s.AddUint64(ctxt.Arch, uint64(tag))
 	} else {
@@ -1057,7 +1027,7 @@
 	return aux
 }
 
-func elfdynhash2(ctxt *Link) {
+func elfdynhash(ctxt *Link) {
 	if !ctxt.IsELF {
 		return
 	}
@@ -1175,23 +1145,23 @@
 	s = ldr.CreateSymForUpdate(".dynamic", 0)
 	elfverneed = nfile
 	if elfverneed != 0 {
-		elfWriteDynEntSym2(ctxt, s, DT_VERNEED, gnuVersionR.Sym())
-		Elfwritedynent2(ctxt.Arch, s, DT_VERNEEDNUM, uint64(nfile))
-		elfWriteDynEntSym2(ctxt, s, DT_VERSYM, gnuVersion.Sym())
+		elfWriteDynEntSym(ctxt, s, DT_VERNEED, gnuVersionR.Sym())
+		Elfwritedynent(ctxt.Arch, s, DT_VERNEEDNUM, uint64(nfile))
+		elfWriteDynEntSym(ctxt, s, DT_VERSYM, gnuVersion.Sym())
 	}
 
 	sy := ldr.CreateSymForUpdate(elfRelType+".plt", 0)
 	if sy.Size() > 0 {
 		if elfRelType == ".rela" {
-			Elfwritedynent2(ctxt.Arch, s, DT_PLTREL, DT_RELA)
+			Elfwritedynent(ctxt.Arch, s, DT_PLTREL, DT_RELA)
 		} else {
-			Elfwritedynent2(ctxt.Arch, s, DT_PLTREL, DT_REL)
+			Elfwritedynent(ctxt.Arch, s, DT_PLTREL, DT_REL)
 		}
-		elfwritedynentsymsize2(ctxt, s, DT_PLTRELSZ, sy.Sym())
-		elfWriteDynEntSym2(ctxt, s, DT_JMPREL, sy.Sym())
+		elfwritedynentsymsize(ctxt, s, DT_PLTRELSZ, sy.Sym())
+		elfWriteDynEntSym(ctxt, s, DT_JMPREL, sy.Sym())
 	}
 
-	Elfwritedynent2(ctxt.Arch, s, DT_NULL, 0)
+	Elfwritedynent(ctxt.Arch, s, DT_NULL, 0)
 }
 
 func elfphload(seg *sym.Segment) *ElfPhdr {
@@ -1373,12 +1343,7 @@
 	return sh
 }
 
-func elfrelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) {
-	if !ctxt.IsAMD64() {
-		elfrelocsect2(ctxt, sect, syms)
-		return
-	}
-
+func elfrelocsect(ctxt *Link, sect *sym.Section, syms []loader.Sym) {
 	// If main section is SHT_NOBITS, nothing to relocate.
 	// Also nothing to relocate in .shstrtab.
 	if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
@@ -1388,43 +1353,43 @@
 		return
 	}
 
+	ldr := ctxt.loader
 	sect.Reloff = uint64(ctxt.Out.Offset())
 	for i, s := range syms {
-		if !s.Attr.Reachable() {
-			continue
+		if !ldr.AttrReachable(s) {
+			panic("should never happen")
 		}
-		if uint64(s.Value) >= sect.Vaddr {
+		if uint64(ldr.SymValue(s)) >= sect.Vaddr {
 			syms = syms[i:]
 			break
 		}
 	}
 
-	ldr := ctxt.loader
 	eaddr := int32(sect.Vaddr + sect.Length)
 	for _, s := range syms {
-		if !s.Attr.Reachable() {
+		if !ldr.AttrReachable(s) {
 			continue
 		}
-		if s.Value >= int64(eaddr) {
+		if ldr.SymValue(s) >= int64(eaddr) {
 			break
 		}
-		i := loader.Sym(s.SymIdx)
-		relocs := ldr.ExtRelocs(i)
+
+		relocs := ldr.ExtRelocs(s)
 		for ri := 0; ri < relocs.Count(); ri++ {
 			r := relocs.At(ri)
 			if r.Xsym == 0 {
-				Errorf(s, "missing xsym in relocation %v", ldr.SymName(r.Sym()))
+				ldr.Errorf(s, "missing xsym in relocation")
 				continue
 			}
-			esr := ElfSymForReloc(ctxt, ldr.Syms[r.Xsym])
+			esr := ElfSymForReloc(ctxt, r.Xsym)
 			if esr == 0 {
-				Errorf(s, "reloc %d (%s) to non-elf symbol %s (outer=%s) %d (%s)", r.Type(), sym.RelocName(ctxt.Arch, r.Type()), ldr.Syms[r.Sym()].Name, ldr.Syms[r.Xsym].Name, ldr.Syms[r.Sym()].Type, ldr.Syms[r.Sym()].Type)
+				ldr.Errorf(s, "reloc %d (%s) to non-elf symbol %s (outer=%s) %d (%s)", r.Type(), sym.RelocName(ctxt.Arch, r.Type()), ldr.SymName(r.Sym()), ldr.SymName(r.Xsym), ldr.SymType(r.Sym()), ldr.SymType(r.Sym()).String())
 			}
 			if !ldr.AttrReachable(r.Xsym) {
-				Errorf(s, "unreachable reloc %d (%s) target %v", r.Type(), sym.RelocName(ctxt.Arch, r.Type()), ldr.Syms[r.Xsym].Name)
+				ldr.Errorf(s, "unreachable reloc %d (%s) target %v", r.Type(), sym.RelocName(ctxt.Arch, r.Type()), ldr.SymName(r.Xsym))
 			}
-			if !thearch.Elfreloc2(ctxt, ldr, i, 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(), ldr.Syms[r.Sym()].Name)
+			if !thearch.Elfreloc1(ctxt, ldr, s, r, int64(uint64(ldr.SymValue(s)+int64(r.Off()))-sect.Vaddr)) {
+				ldr.Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type, sym.RelocName(ctxt.Arch, r.Type()), r.Siz(), ldr.SymName(r.Sym()))
 			}
 		}
 	}
@@ -1432,7 +1397,8 @@
 	sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
 }
 
-func Elfemitreloc(ctxt *Link) {
+func elfEmitReloc(ctxt *Link) {
+
 	for ctxt.Out.Offset()&7 != 0 {
 		ctxt.Out.Write8(0)
 	}
@@ -1457,8 +1423,8 @@
 	for i := 0; i < len(Segdwarf.Sections); i++ {
 		sect := Segdwarf.Sections[i]
 		si := dwarfp[i]
-		if si.secSym() != sect.Sym ||
-			si.secSym().Sect != sect {
+		if si.secSym() != loader.Sym(sect.Sym) ||
+			ctxt.loader.SymSect(si.secSym()) != sect {
 			panic("inconsistency between dwarfp and Segdwarf")
 		}
 		elfrelocsect(ctxt, sect, si.syms)
@@ -1689,47 +1655,47 @@
 		/*
 		 * .dynamic table
 		 */
-		elfwritedynentsym2(ctxt, dynamic, DT_HASH, hash.Sym())
+		elfwritedynentsym(ctxt, dynamic, DT_HASH, hash.Sym())
 
-		elfwritedynentsym2(ctxt, dynamic, DT_SYMTAB, dynsym.Sym())
+		elfwritedynentsym(ctxt, dynamic, DT_SYMTAB, dynsym.Sym())
 		if elf64 {
-			Elfwritedynent2(ctxt.Arch, dynamic, DT_SYMENT, ELF64SYMSIZE)
+			Elfwritedynent(ctxt.Arch, dynamic, DT_SYMENT, ELF64SYMSIZE)
 		} else {
-			Elfwritedynent2(ctxt.Arch, dynamic, DT_SYMENT, ELF32SYMSIZE)
+			Elfwritedynent(ctxt.Arch, dynamic, DT_SYMENT, ELF32SYMSIZE)
 		}
-		elfwritedynentsym2(ctxt, dynamic, DT_STRTAB, dynstr.Sym())
-		elfwritedynentsymsize2(ctxt, dynamic, DT_STRSZ, dynstr.Sym())
+		elfwritedynentsym(ctxt, dynamic, DT_STRTAB, dynstr.Sym())
+		elfwritedynentsymsize(ctxt, dynamic, DT_STRSZ, dynstr.Sym())
 		if elfRelType == ".rela" {
 			rela := ldr.LookupOrCreateSym(".rela", 0)
-			elfwritedynentsym2(ctxt, dynamic, DT_RELA, rela)
-			elfwritedynentsymsize2(ctxt, dynamic, DT_RELASZ, rela)
-			Elfwritedynent2(ctxt.Arch, dynamic, DT_RELAENT, ELF64RELASIZE)
+			elfwritedynentsym(ctxt, dynamic, DT_RELA, rela)
+			elfwritedynentsymsize(ctxt, dynamic, DT_RELASZ, rela)
+			Elfwritedynent(ctxt.Arch, dynamic, DT_RELAENT, ELF64RELASIZE)
 		} else {
 			rel := ldr.LookupOrCreateSym(".rel", 0)
-			elfwritedynentsym2(ctxt, dynamic, DT_REL, rel)
-			elfwritedynentsymsize2(ctxt, dynamic, DT_RELSZ, rel)
-			Elfwritedynent2(ctxt.Arch, dynamic, DT_RELENT, ELF32RELSIZE)
+			elfwritedynentsym(ctxt, dynamic, DT_REL, rel)
+			elfwritedynentsymsize(ctxt, dynamic, DT_RELSZ, rel)
+			Elfwritedynent(ctxt.Arch, dynamic, DT_RELENT, ELF32RELSIZE)
 		}
 
 		if rpath.val != "" {
-			Elfwritedynent2(ctxt.Arch, dynamic, DT_RUNPATH, uint64(dynstr.Addstring(rpath.val)))
+			Elfwritedynent(ctxt.Arch, dynamic, DT_RUNPATH, uint64(dynstr.Addstring(rpath.val)))
 		}
 
 		if ctxt.IsPPC64() {
-			elfwritedynentsym2(ctxt, dynamic, DT_PLTGOT, plt.Sym())
+			elfwritedynentsym(ctxt, dynamic, DT_PLTGOT, plt.Sym())
 		} else {
-			elfwritedynentsym2(ctxt, dynamic, DT_PLTGOT, gotplt.Sym())
+			elfwritedynentsym(ctxt, dynamic, DT_PLTGOT, gotplt.Sym())
 		}
 
 		if ctxt.IsPPC64() {
-			Elfwritedynent2(ctxt.Arch, dynamic, DT_PPC64_OPT, 0)
+			Elfwritedynent(ctxt.Arch, dynamic, 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.
-		Elfwritedynent2(ctxt.Arch, dynamic, DT_DEBUG, 0)
+		Elfwritedynent(ctxt.Arch, dynamic, DT_DEBUG, 0)
 	}
 
 	if ctxt.IsShared() {
@@ -1746,7 +1712,7 @@
 		sort.Sort(byPkg(ctxt.Library))
 		h := sha1.New()
 		for _, l := range ctxt.Library {
-			io.WriteString(h, l.Hash)
+			h.Write(l.Fingerprint[:])
 		}
 		addgonote(ctxt, ".note.go.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{}))
 		addgonote(ctxt, ".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote)
@@ -1763,13 +1729,16 @@
 }
 
 // Do not write DT_NULL.  elfdynhash will finish it.
-func shsym(sh *ElfShdr, s *sym.Symbol) {
-	addr := Symaddr(s)
+func shsym(sh *ElfShdr, ldr *loader.Loader, s loader.Sym) {
+	if s == 0 {
+		panic("bad symbol in shsym2")
+	}
+	addr := ldr.SymValue(s)
 	if sh.flags&SHF_ALLOC != 0 {
 		sh.addr = uint64(addr)
 	}
-	sh.off = uint64(datoff(s, addr))
-	sh.size = uint64(s.Size)
+	sh.off = uint64(datoff(ldr, s, addr))
+	sh.size = uint64(ldr.SymSize(s))
 }
 
 func phsh(ph *ElfPhdr, sh *ElfShdr) {
@@ -1810,7 +1779,21 @@
 	}
 }
 
-func Asmbelf(ctxt *Link, symo int64) {
+func asmbElf(ctxt *Link) {
+	var symo int64
+	if !*FlagS {
+		symo = int64(Segdwarf.Fileoff + Segdwarf.Filelen)
+		symo = Rnd(symo, int64(*FlagRound))
+		ctxt.Out.SeekSet(symo)
+		asmElfSym(ctxt)
+		ctxt.Out.Write(Elfstrdat)
+		if ctxt.IsExternal() {
+			elfEmitReloc(ctxt)
+		}
+	}
+	ctxt.Out.SeekSet(0)
+
+	ldr := ctxt.loader
 	eh := getElfEhdr()
 	switch ctxt.Arch.Family {
 	default:
@@ -2029,22 +2012,22 @@
 		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)
+		s := ldr.Lookup(".dynsym", 0)
 		i := uint32(0)
-		for sub := s; sub != nil; sub = symSub(ctxt, sub) {
+		for sub := s; sub != 0; sub = ldr.SubSym(sub) {
 			i++
-			if !sub.Attr.Local() {
+			if !ldr.AttrLocal(sub) {
 				break
 			}
 		}
 		sh.info = i
-		shsym(sh, s)
+		shsym(sh, ldr, s)
 
 		sh = elfshname(".dynstr")
 		sh.type_ = SHT_STRTAB
 		sh.flags = SHF_ALLOC
 		sh.addralign = 1
-		shsym(sh, ctxt.Syms.Lookup(".dynstr", 0))
+		shsym(sh, ldr, ldr.Lookup(".dynstr", 0))
 
 		if elfverneed != 0 {
 			sh := elfshname(".gnu.version")
@@ -2053,7 +2036,7 @@
 			sh.addralign = 2
 			sh.link = uint32(elfshname(".dynsym").shnum)
 			sh.entsize = 2
-			shsym(sh, ctxt.Syms.Lookup(".gnu.version", 0))
+			shsym(sh, ldr, ldr.Lookup(".gnu.version", 0))
 
 			sh = elfshname(".gnu.version_r")
 			sh.type_ = SHT_GNU_VERNEED
@@ -2061,7 +2044,7 @@
 			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))
+			shsym(sh, ldr, ldr.Lookup(".gnu.version_r", 0))
 		}
 
 		if elfRelType == ".rela" {
@@ -2072,7 +2055,7 @@
 			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))
+			shsym(sh, ldr, ldr.Lookup(".rela.plt", 0))
 
 			sh = elfshname(".rela")
 			sh.type_ = SHT_RELA
@@ -2080,7 +2063,7 @@
 			sh.entsize = ELF64RELASIZE
 			sh.addralign = 8
 			sh.link = uint32(elfshname(".dynsym").shnum)
-			shsym(sh, ctxt.Syms.Lookup(".rela", 0))
+			shsym(sh, ldr, ldr.Lookup(".rela", 0))
 		} else {
 			sh := elfshname(".rel.plt")
 			sh.type_ = SHT_REL
@@ -2088,7 +2071,7 @@
 			sh.entsize = ELF32RELSIZE
 			sh.addralign = 4
 			sh.link = uint32(elfshname(".dynsym").shnum)
-			shsym(sh, ctxt.Syms.Lookup(".rel.plt", 0))
+			shsym(sh, ldr, ldr.Lookup(".rel.plt", 0))
 
 			sh = elfshname(".rel")
 			sh.type_ = SHT_REL
@@ -2096,7 +2079,7 @@
 			sh.entsize = ELF32RELSIZE
 			sh.addralign = 4
 			sh.link = uint32(elfshname(".dynsym").shnum)
-			shsym(sh, ctxt.Syms.Lookup(".rel", 0))
+			shsym(sh, ldr, ldr.Lookup(".rel", 0))
 		}
 
 		if eh.machine == EM_PPC64 {
@@ -2104,7 +2087,7 @@
 			sh.type_ = SHT_PROGBITS
 			sh.flags = SHF_ALLOC + SHF_EXECINSTR
 			sh.addralign = 4
-			shsym(sh, ctxt.Syms.Lookup(".glink", 0))
+			shsym(sh, ldr, ldr.Lookup(".glink", 0))
 		}
 
 		sh = elfshname(".plt")
@@ -2125,7 +2108,7 @@
 			sh.entsize = 4
 		}
 		sh.addralign = sh.entsize
-		shsym(sh, ctxt.Syms.Lookup(".plt", 0))
+		shsym(sh, ldr, ldr.Lookup(".plt", 0))
 
 		// On ppc64, .got comes from the input files, so don't
 		// create it here, and .got.plt is not used.
@@ -2135,14 +2118,14 @@
 			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))
+			shsym(sh, ldr, ldr.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))
+			shsym(sh, ldr, ldr.Lookup(".got.plt", 0))
 		}
 
 		sh = elfshname(".hash")
@@ -2151,7 +2134,7 @@
 		sh.entsize = 4
 		sh.addralign = uint64(ctxt.Arch.RegSize)
 		sh.link = uint32(elfshname(".dynsym").shnum)
-		shsym(sh, ctxt.Syms.Lookup(".hash", 0))
+		shsym(sh, ldr, ldr.Lookup(".hash", 0))
 
 		/* sh and PT_DYNAMIC for .dynamic section */
 		sh = elfshname(".dynamic")
@@ -2161,7 +2144,7 @@
 		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))
+		shsym(sh, ldr, ldr.Lookup(".dynamic", 0))
 		ph := newElfPhdr()
 		ph.type_ = PT_DYNAMIC
 		ph.flags = PF_R + PF_W
@@ -2205,7 +2188,7 @@
 	sh := elfshname(".shstrtab")
 	sh.type_ = SHT_STRTAB
 	sh.addralign = 1
-	shsym(sh, ctxt.Syms.Lookup(".shstrtab", 0))
+	shsym(sh, ldr, ldr.Lookup(".shstrtab", 0))
 	eh.shstrndx = uint16(sh.shnum)
 
 	// put these sections early in the list
@@ -2244,8 +2227,8 @@
 			elfshreloc(ctxt.Arch, sect)
 		}
 		for _, si := range dwarfp {
-			s := si.secSym()
-			elfshreloc(ctxt.Arch, s.Sect)
+			sect := ldr.SymSect(si.secSym())
+			elfshreloc(ctxt.Arch, sect)
 		}
 		// add a .note.GNU-stack section to mark the stack as non-executable
 		sh := elfshname(".note.GNU-stack")
@@ -2259,7 +2242,7 @@
 		sh := elfshname(".symtab")
 		sh.type_ = SHT_SYMTAB
 		sh.off = uint64(symo)
-		sh.size = uint64(Symsize)
+		sh.size = uint64(symSize)
 		sh.addralign = uint64(ctxt.Arch.RegSize)
 		sh.entsize = 8 + 2*uint64(ctxt.Arch.RegSize)
 		sh.link = uint32(elfshname(".strtab").shnum)
@@ -2267,7 +2250,7 @@
 
 		sh = elfshname(".strtab")
 		sh.type_ = SHT_STRTAB
-		sh.off = uint64(symo) + uint64(Symsize)
+		sh.off = uint64(symo) + uint64(symSize)
 		sh.size = uint64(len(Elfstrdat))
 		sh.addralign = 1
 	}
@@ -2349,12 +2332,12 @@
 	}
 }
 
-func elfadddynsym2(ldr *loader.Loader, target *Target, syms *ArchSyms, s loader.Sym) {
+func elfadddynsym(ldr *loader.Loader, target *Target, syms *ArchSyms, s loader.Sym) {
 	ldr.SetSymDynid(s, int32(Nelfsym))
 	Nelfsym++
-	d := ldr.MakeSymbolUpdater(syms.DynSym2)
+	d := ldr.MakeSymbolUpdater(syms.DynSym)
 	name := ldr.SymExtname(s)
-	dstru := ldr.MakeSymbolUpdater(syms.DynStr2)
+	dstru := ldr.MakeSymbolUpdater(syms.DynStr)
 	st := ldr.SymType(s)
 	cgoeStatic := ldr.AttrCgoExportStatic(s)
 	cgoeDynamic := ldr.AttrCgoExportDynamic(s)
@@ -2397,8 +2380,8 @@
 		dil := ldr.SymDynimplib(s)
 
 		if target.Arch.Family == sys.AMD64 && !cgoeDynamic && dil != "" && !seenlib[dil] {
-			du := ldr.MakeSymbolUpdater(syms.Dynamic2)
-			Elfwritedynent2(target.Arch, du, DT_NEEDED, uint64(dstru.Addstring(dil)))
+			du := ldr.MakeSymbolUpdater(syms.Dynamic)
+			Elfwritedynent(target.Arch, du, DT_NEEDED, uint64(dstru.Addstring(dil)))
 		}
 	} else {
 
diff --git a/src/cmd/link/internal/ld/elf2.go b/src/cmd/link/internal/ld/elf2.go
deleted file mode 100644
index 07b64cf..0000000
--- a/src/cmd/link/internal/ld/elf2.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2020 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/link/internal/sym"
-)
-
-// Temporary dumping around for sym.Symbol version of helper
-// functions in elf.go, still being used for some archs/oses.
-// FIXME: get rid of this file when dodata() is completely
-// converted and the sym.Symbol functions are not needed.
-
-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 elfrelocsect2(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
-			}
-			esr := ElfSymForReloc(ctxt, r.Xsym)
-			if esr == 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
-}
diff --git a/src/cmd/link/internal/ld/errors.go b/src/cmd/link/internal/ld/errors.go
index c2c191d..c5ce097 100644
--- a/src/cmd/link/internal/ld/errors.go
+++ b/src/cmd/link/internal/ld/errors.go
@@ -15,12 +15,6 @@
 	to   loader.Sym // Unresolved symbol referenced by "from"
 }
 
-type unresolvedSymKey2 struct {
-	from *sym.Symbol // Symbol that referenced unresolved "to"
-	to   *sym.Symbol // Unresolved symbol referenced by "from"
-}
-
-type lookupFn func(name string, version int) *sym.Symbol
 type symNameFn func(s loader.Sym) string
 
 // ErrorReporter is used to make error reporting thread safe.
@@ -28,9 +22,7 @@
 	loader.ErrorReporter
 	unresOnce  sync.Once
 	unresSyms  map[unresolvedSymKey]bool
-	unresSyms2 map[unresolvedSymKey2]bool
 	unresMutex sync.Mutex
-	lookup     lookupFn
 	SymName    symNameFn
 }
 
@@ -71,40 +63,3 @@
 		}
 	}
 }
-
-// errorUnresolved2 prints unresolved symbol error for r.Sym that is referenced from s.
-func (reporter *ErrorReporter) errorUnresolved2(s *sym.Symbol, r *sym.Reloc) {
-	reporter.unresOnce.Do(func() { reporter.unresSyms2 = make(map[unresolvedSymKey2]bool) })
-
-	k := unresolvedSymKey2{from: s, to: r.Sym}
-	reporter.unresMutex.Lock()
-	defer reporter.unresMutex.Unlock()
-	if !reporter.unresSyms2[k] {
-		reporter.unresSyms2[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 := reporter.lookup(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)
-		}
-	}
-}
diff --git a/src/cmd/link/internal/ld/go.go b/src/cmd/link/internal/ld/go.go
index 9a63a3a..6d05c59 100644
--- a/src/cmd/link/internal/ld/go.go
+++ b/src/cmd/link/internal/ld/go.go
@@ -27,17 +27,6 @@
 	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
@@ -50,18 +39,12 @@
 
 	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)
@@ -74,9 +57,6 @@
 		} else {
 			line, data = data, ""
 		}
-		if line == "safe" {
-			lib.Safe = true
-		}
 		if line == "main" {
 			lib.Main = true
 		}
@@ -93,9 +73,6 @@
 		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
@@ -106,9 +83,6 @@
 		}
 		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
@@ -320,24 +294,24 @@
 	seenlib[lib] = true
 
 	if ctxt.IsELF {
-		dsu := ctxt.loader.MakeSymbolUpdater(ctxt.DynStr2)
+		dsu := ctxt.loader.MakeSymbolUpdater(ctxt.DynStr)
 		if dsu.Size() == 0 {
 			dsu.Addstring("")
 		}
-		du := ctxt.loader.MakeSymbolUpdater(ctxt.Dynamic2)
-		Elfwritedynent2(ctxt.Arch, du, DT_NEEDED, uint64(dsu.Addstring(lib)))
+		du := ctxt.loader.MakeSymbolUpdater(ctxt.Dynamic)
+		Elfwritedynent(ctxt.Arch, du, DT_NEEDED, uint64(dsu.Addstring(lib)))
 	} else {
 		Errorf(nil, "adddynlib: unsupported binary format")
 	}
 }
 
-func Adddynsym2(ldr *loader.Loader, target *Target, syms *ArchSyms, s loader.Sym) {
+func Adddynsym(ldr *loader.Loader, target *Target, syms *ArchSyms, s loader.Sym) {
 	if ldr.SymDynid(s) >= 0 || target.LinkMode == LinkExternal {
 		return
 	}
 
 	if target.IsELF {
-		elfadddynsym2(ldr, target, syms, s)
+		elfadddynsym(ldr, target, syms, s)
 	} else if target.HeadType == objabi.Hdarwin {
 		ldr.Errorf(s, "adddynsym: missed symbol (Extname=%s)", ldr.SymExtname(s))
 	} else if target.HeadType == objabi.Hwindows {
@@ -351,19 +325,15 @@
 	var buf bytes.Buffer
 	for i := loader.Sym(1); i < loader.Sym(l.NSym()); i++ {
 		if name := l.SymName(i); strings.HasPrefix(name, "go.track.") {
-			bld := l.MakeSymbolUpdater(i)
-			bld.SetSpecial(true)
-			bld.SetNotInSymbolTable(true)
-			if bld.Reachable() {
+			if l.AttrReachable(i) {
+				l.SetAttrSpecial(i, true)
+				l.SetAttrNotInSymbolTable(i, true)
 				buf.WriteString(name[9:])
 				for p := l.Reachparent[i]; p != 0; p = l.Reachparent[p] {
 					buf.WriteString("\t")
 					buf.WriteString(l.SymName(p))
 				}
 				buf.WriteString("\n")
-
-				bld.SetType(sym.SCONST)
-				bld.SetValue(0)
 			}
 		}
 	}
@@ -383,7 +353,7 @@
 func (ctxt *Link) addexport() {
 	// Track undefined external symbols during external link.
 	if ctxt.LinkMode == LinkExternal {
-		for _, s := range ctxt.Textp2 {
+		for _, s := range ctxt.Textp {
 			if ctxt.loader.AttrSpecial(s) || ctxt.loader.AttrSubSymbol(s) {
 				continue
 			}
@@ -408,8 +378,8 @@
 		return
 	}
 
-	for _, exp := range ctxt.dynexp2 {
-		Adddynsym2(ctxt.loader, &ctxt.Target, &ctxt.ArchSyms, exp)
+	for _, exp := range ctxt.dynexp {
+		Adddynsym(ctxt.loader, &ctxt.Target, &ctxt.ArchSyms, exp)
 	}
 	for _, lib := range dynlib {
 		adddynlib(ctxt, lib)
diff --git a/src/cmd/link/internal/ld/heap.go b/src/cmd/link/internal/ld/heap.go
new file mode 100644
index 0000000..ea2d772
--- /dev/null
+++ b/src/cmd/link/internal/ld/heap.go
@@ -0,0 +1,54 @@
+// Copyright 2020 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/link/internal/loader"
+
+// Min-heap implementation, for the deadcode pass.
+// Specialized for loader.Sym elements.
+
+type heap []loader.Sym
+
+func (h *heap) push(s loader.Sym) {
+	*h = append(*h, s)
+	// sift up
+	n := len(*h) - 1
+	for n > 0 {
+		p := (n - 1) / 2 // parent
+		if (*h)[p] <= (*h)[n] {
+			break
+		}
+		(*h)[n], (*h)[p] = (*h)[p], (*h)[n]
+		n = p
+	}
+}
+
+func (h *heap) pop() loader.Sym {
+	r := (*h)[0]
+	n := len(*h) - 1
+	(*h)[0] = (*h)[n]
+	*h = (*h)[:n]
+
+	// sift down
+	i := 0
+	for {
+		c := 2*i + 1 // left child
+		if c >= n {
+			break
+		}
+		if c1 := c + 1; c1 < n && (*h)[c1] < (*h)[c] {
+			c = c1 // right child
+		}
+		if (*h)[i] <= (*h)[c] {
+			break
+		}
+		(*h)[i], (*h)[c] = (*h)[c], (*h)[i]
+		i = c
+	}
+
+	return r
+}
+
+func (h *heap) empty() bool { return len(*h) == 0 }
diff --git a/src/cmd/link/internal/ld/heap_test.go b/src/cmd/link/internal/ld/heap_test.go
new file mode 100644
index 0000000..08c9030
--- /dev/null
+++ b/src/cmd/link/internal/ld/heap_test.go
@@ -0,0 +1,90 @@
+// Copyright 2020 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/link/internal/loader"
+	"testing"
+)
+
+func TestHeap(t *testing.T) {
+	tests := [][]loader.Sym{
+		{10, 20, 30, 40, 50, 60, 70, 80, 90, 100},
+		{100, 90, 80, 70, 60, 50, 40, 30, 20, 10},
+		{30, 50, 80, 20, 60, 70, 10, 100, 90, 40},
+	}
+	for _, s := range tests {
+		h := heap{}
+		for _, i := range s {
+			h.push(i)
+			if !verify(&h, 0) {
+				t.Errorf("heap invariant violated: %v", h)
+			}
+		}
+		for j := 0; j < len(s); j++ {
+			x := h.pop()
+			if !verify(&h, 0) {
+				t.Errorf("heap invariant violated: %v", h)
+			}
+			// pop should return elements in ascending order.
+			if want := loader.Sym((j + 1) * 10); x != want {
+				t.Errorf("pop returns wrong element: want %d, got %d", want, x)
+			}
+		}
+		if !h.empty() {
+			t.Errorf("heap is not empty after all pops")
+		}
+	}
+
+	// Also check that mixed pushes and pops work correctly.
+	for _, s := range tests {
+		h := heap{}
+		for i := 0; i < len(s)/2; i++ {
+			// two pushes, one pop
+			h.push(s[2*i])
+			if !verify(&h, 0) {
+				t.Errorf("heap invariant violated: %v", h)
+			}
+			h.push(s[2*i+1])
+			if !verify(&h, 0) {
+				t.Errorf("heap invariant violated: %v", h)
+			}
+			h.pop()
+			if !verify(&h, 0) {
+				t.Errorf("heap invariant violated: %v", h)
+			}
+		}
+		for !h.empty() { // pop remaining elements
+			h.pop()
+			if !verify(&h, 0) {
+				t.Errorf("heap invariant violated: %v", h)
+			}
+		}
+	}
+}
+
+// recursively verify heap-ness, starting at element i.
+func verify(h *heap, i int) bool {
+	n := len(*h)
+	c1 := 2*i + 1 // left child
+	c2 := 2*i + 2 // right child
+	if c1 < n {
+		if (*h)[c1] < (*h)[i] {
+			return false
+		}
+		if !verify(h, c1) {
+			return false
+		}
+	}
+	if c2 < n {
+		if (*h)[c2] < (*h)[i] {
+			return false
+		}
+		if !verify(h, c2) {
+			return false
+		}
+	}
+	return true
+}
diff --git a/src/cmd/link/internal/ld/ld.go b/src/cmd/link/internal/ld/ld.go
index 71f388b..0846439 100644
--- a/src/cmd/link/internal/ld/ld.go
+++ b/src/cmd/link/internal/ld/ld.go
@@ -248,11 +248,11 @@
 	ctxt.loader.SetAttrLocal(ifs, true)
 	initfunc.SetType(sym.STEXT)
 
-	// Add the init func and/or addmoduledata to Textp2.
+	// Add the init func and/or addmoduledata to Textp.
 	if ctxt.BuildMode == BuildModePlugin {
-		ctxt.Textp2 = append(ctxt.Textp2, amd)
+		ctxt.Textp = append(ctxt.Textp, amd)
 	}
-	ctxt.Textp2 = append(ctxt.Textp2, initfunc.Sym())
+	ctxt.Textp = append(ctxt.Textp, initfunc.Sym())
 
 	// Create an init array entry
 	amdi := ctxt.loader.LookupOrCreateSym("go.link.addmoduledatainit", 0)
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index 61ccc28..a747cde 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -48,7 +48,6 @@
 	"debug/macho"
 	"encoding/base64"
 	"encoding/binary"
-	"encoding/hex"
 	"fmt"
 	"io"
 	"io/ioutil"
@@ -94,100 +93,56 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
-type LookupFn func(name string, version int) *sym.Symbol
-
 // ArchSyms holds a number of architecture specific symbols used during
 // relocation.  Rather than allowing them universal access to all symbols,
 // we keep a subset for relocation application.
 type ArchSyms struct {
-	TOC    *sym.Symbol
-	DotTOC []*sym.Symbol // for each version
+	Rel     loader.Sym
+	Rela    loader.Sym
+	RelPLT  loader.Sym
+	RelaPLT loader.Sym
 
-	GOT    *sym.Symbol
-	PLT    *sym.Symbol
-	GOTPLT *sym.Symbol
+	LinkEditGOT loader.Sym
+	LinkEditPLT loader.Sym
 
-	Tlsg      *sym.Symbol
+	TOC    loader.Sym
+	DotTOC []loader.Sym // for each version
+
+	GOT    loader.Sym
+	PLT    loader.Sym
+	GOTPLT loader.Sym
+
+	Tlsg      loader.Sym
 	Tlsoffset int
 
-	Dynamic *sym.Symbol
-	DynSym  *sym.Symbol
-	DynStr  *sym.Symbol
-
-	// Elf specific
-	Rel     *sym.Symbol
-	Rela    *sym.Symbol
-	RelPLT  *sym.Symbol
-	RelaPLT *sym.Symbol
-
-	// Darwin symbols
-	LinkEditGOT *sym.Symbol
-	LinkEditPLT *sym.Symbol
-
-	// ----- loader.Sym equivalents -----
-
-	Rel2     loader.Sym
-	Rela2    loader.Sym
-	RelPLT2  loader.Sym
-	RelaPLT2 loader.Sym
-
-	LinkEditGOT2 loader.Sym
-	LinkEditPLT2 loader.Sym
-
-	TOC2    loader.Sym
-	DotTOC2 []loader.Sym // for each version
-
-	GOT2    loader.Sym
-	PLT2    loader.Sym
-	GOTPLT2 loader.Sym
-
-	Tlsg2 loader.Sym
-
-	Dynamic2 loader.Sym
-	DynSym2  loader.Sym
-	DynStr2  loader.Sym
+	Dynamic loader.Sym
+	DynSym  loader.Sym
+	DynStr  loader.Sym
 }
 
-const BeforeLoadlibFull = 1
-const AfterLoadlibFull = 2
-
-// mkArchSym is a helper for setArchSyms, invoked once before loadlibfull
-// and once after. On the first call it creates a loader.Sym with the
-// specified name, and on the second call a corresponding sym.Symbol.
-func (ctxt *Link) mkArchSym(which int, name string, ver int, ls *loader.Sym, ss **sym.Symbol) {
-	if which == BeforeLoadlibFull {
-		*ls = ctxt.loader.LookupOrCreateSym(name, ver)
-	} else {
-		*ss = ctxt.loader.Syms[*ls]
-	}
+// mkArchSym is a helper for setArchSyms, to set up a special symbol.
+func (ctxt *Link) mkArchSym(name string, ver int, ls *loader.Sym) {
+	*ls = ctxt.loader.LookupOrCreateSym(name, ver)
 }
 
 // mkArchVecSym is similar to  setArchSyms, but operates on elements within
 // a slice, where each element corresponds to some symbol version.
-func (ctxt *Link) mkArchSymVec(which int, name string, ver int, ls []loader.Sym, ss []*sym.Symbol) {
-	if which == BeforeLoadlibFull {
-		ls[ver] = ctxt.loader.LookupOrCreateSym(name, ver)
-	} else if ls[ver] != 0 {
-		ss[ver] = ctxt.loader.Syms[ls[ver]]
-	}
+func (ctxt *Link) mkArchSymVec(name string, ver int, ls []loader.Sym) {
+	ls[ver] = ctxt.loader.LookupOrCreateSym(name, ver)
 }
 
 // setArchSyms sets up the ArchSyms structure, and must be called before
-// relocations are applied. This function is invoked twice, once prior
-// to loadlibfull(), and once after the work of loadlibfull is complete.
-func (ctxt *Link) setArchSyms(which int) {
-	if which != BeforeLoadlibFull && which != AfterLoadlibFull {
-		panic("internal error")
-	}
-	ctxt.mkArchSym(which, ".got", 0, &ctxt.GOT2, &ctxt.GOT)
-	ctxt.mkArchSym(which, ".plt", 0, &ctxt.PLT2, &ctxt.PLT)
-	ctxt.mkArchSym(which, ".got.plt", 0, &ctxt.GOTPLT2, &ctxt.GOTPLT)
-	ctxt.mkArchSym(which, ".dynamic", 0, &ctxt.Dynamic2, &ctxt.Dynamic)
-	ctxt.mkArchSym(which, ".dynsym", 0, &ctxt.DynSym2, &ctxt.DynSym)
-	ctxt.mkArchSym(which, ".dynstr", 0, &ctxt.DynStr2, &ctxt.DynStr)
+// relocations are applied.
+func (ctxt *Link) setArchSyms() {
+	ctxt.mkArchSym(".got", 0, &ctxt.GOT)
+	ctxt.mkArchSym(".plt", 0, &ctxt.PLT)
+	ctxt.mkArchSym(".got.plt", 0, &ctxt.GOTPLT)
+	ctxt.mkArchSym(".dynamic", 0, &ctxt.Dynamic)
+	ctxt.mkArchSym(".dynsym", 0, &ctxt.DynSym)
+	ctxt.mkArchSym(".dynstr", 0, &ctxt.DynStr)
 
 	if ctxt.IsPPC64() {
-		ctxt.mkArchSym(which, "TOC", 0, &ctxt.TOC2, &ctxt.TOC)
+		ctxt.mkArchSym("TOC", 0, &ctxt.TOC)
 
 		// NB: note the +2 below for DotTOC2 compared to the +1 for
 		// DocTOC. This is because loadlibfull() creates an additional
@@ -195,27 +150,24 @@
 		// *sym.Symbol symbols. Symbols that are assigned this final
 		// version are not going to have TOC references, so it should
 		// be ok for them to inherit an invalid .TOC. symbol.
-		if which == BeforeLoadlibFull {
-			ctxt.DotTOC2 = make([]loader.Sym, ctxt.Syms.MaxVersion()+2)
-		} else {
-			ctxt.DotTOC = make([]*sym.Symbol, ctxt.Syms.MaxVersion()+1)
-		}
-		for i := 0; i <= ctxt.Syms.MaxVersion(); i++ {
+		// TODO: revisit the +2, now that loadlibfull is gone.
+		ctxt.DotTOC = make([]loader.Sym, ctxt.MaxVersion()+2)
+		for i := 0; i <= ctxt.MaxVersion(); i++ {
 			if i >= 2 && i < sym.SymVerStatic { // these versions are not used currently
 				continue
 			}
-			ctxt.mkArchSymVec(which, ".TOC.", i, ctxt.DotTOC2, ctxt.DotTOC)
+			ctxt.mkArchSymVec(".TOC.", i, ctxt.DotTOC)
 		}
 	}
 	if ctxt.IsElf() {
-		ctxt.mkArchSym(which, ".rel", 0, &ctxt.Rel2, &ctxt.Rel)
-		ctxt.mkArchSym(which, ".rela", 0, &ctxt.Rela2, &ctxt.Rela)
-		ctxt.mkArchSym(which, ".rel.plt", 0, &ctxt.RelPLT2, &ctxt.RelPLT)
-		ctxt.mkArchSym(which, ".rela.plt", 0, &ctxt.RelaPLT2, &ctxt.RelaPLT)
+		ctxt.mkArchSym(".rel", 0, &ctxt.Rel)
+		ctxt.mkArchSym(".rela", 0, &ctxt.Rela)
+		ctxt.mkArchSym(".rel.plt", 0, &ctxt.RelPLT)
+		ctxt.mkArchSym(".rela.plt", 0, &ctxt.RelaPLT)
 	}
 	if ctxt.IsDarwin() {
-		ctxt.mkArchSym(which, ".linkedit.got", 0, &ctxt.LinkEditGOT2, &ctxt.LinkEditGOT)
-		ctxt.mkArchSym(which, ".linkedit.plt", 0, &ctxt.LinkEditPLT2, &ctxt.LinkEditPLT)
+		ctxt.mkArchSym(".linkedit.got", 0, &ctxt.LinkEditGOT)
+		ctxt.mkArchSym(".linkedit.plt", 0, &ctxt.LinkEditPLT)
 	}
 }
 
@@ -232,9 +184,22 @@
 	Openbsddynld   string
 	Dragonflydynld string
 	Solarisdynld   string
-	Adddynrel      func(*Target, *loader.Loader, *ArchSyms, *sym.Symbol, *sym.Reloc) bool
-	Adddynrel2     func(*Target, *loader.Loader, *ArchSyms, loader.Sym, loader.Reloc2, int) bool
-	Archinit       func(*Link)
+
+	// Empty spaces between codeblocks will be padded with this value.
+	// For example an architecture might want to pad with a trap instruction to
+	// catch wayward programs. Architectures that do not define a padding value
+	// are padded with zeros.
+	CodePad []byte
+
+	// Set to true to write all text blocks in with CodeBlkWrite
+	WriteTextBlocks bool
+
+	// Plan 9 variables.
+	Plan9Magic  uint32
+	Plan9_64Bit bool
+
+	Adddynrel func(*Target, *loader.Loader, *ArchSyms, loader.Sym, loader.Reloc2, int) 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
@@ -244,9 +209,8 @@
 	// same spot in sym.P), a boolean indicating if the external relocations'
 	// been used, and a boolean indicating success/failure (a failing value
 	// indicates a fatal error).
-	Archreloc func(target *Target, syms *ArchSyms, rel *sym.Reloc, sym *sym.Symbol,
-		offset int64) (relocatedOffset int64, success bool)
-	Archreloc2 func(*Target, *loader.Loader, *ArchSyms, loader.Reloc2, *loader.ExtReloc, loader.Sym, int64) (int64, bool, bool)
+	Archreloc func(*Target, *loader.Loader, *ArchSyms, loader.Reloc2, *loader.ExtReloc,
+		loader.Sym, int64) (relocatedOffset int64, needExtReloc bool, ok 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 !=
@@ -255,28 +219,29 @@
 	// 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(target *Target, syms *ArchSyms, rel *sym.Reloc, sym *sym.Symbol,
-		offset int64) (relocatedOffset int64)
+	Archrelocvariant func(target *Target, ldr *loader.Loader, rel loader.Reloc2,
+		rv sym.RelocVariant, sym loader.Sym, offset int64) (relocatedOffset int64)
 
 	// Generate a trampoline for a call from s to rs if necessary. ri is
 	// index of the relocation.
 	Trampoline func(ctxt *Link, ldr *loader.Loader, ri int, rs, s loader.Sym)
 
-	// 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.
+	// Assembling the binary breaks into two phases, writing the code/data/
+	// dwarf information (which is rather generic), and some more architecture
+	// specific work like setting up the elf headers/dynamic relocations, etc.
+	// The phases are called "Asmb" and "Asmb2". Asmb2 needs to be defined for
+	// every architecture, but only if architecture has an Asmb function will
+	// it be used for assembly.  Otherwise a generic assembly Asmb function is
+	// used.
 	Asmb  func(*Link, *loader.Loader)
-	Asmb2 func(*Link)
+	Asmb2 func(*Link, *loader.Loader)
 
-	Elfreloc1   func(*Link, *sym.Reloc, int64) bool
-	Elfreloc2   func(*Link, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool
+	Elfreloc1   func(*Link, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool
 	Elfsetupplt func(ctxt *Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym)
-	Gentext     func(*Link)
-	Gentext2    func(*Link, *loader.Loader)
-	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
+	Gentext     func(*Link, *loader.Loader)
+	Machoreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool
+	PEreloc1    func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool
+	Xcoffreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool
 
 	// TLSIEtoLE converts a TLS Initial Executable relocation to
 	// a TLS Local Executable relocation.
@@ -292,10 +257,10 @@
 
 var (
 	thearch Arch
-	Lcsize  int32
+	lcSize  int32
 	rpath   Rpath
-	Spsize  int32
-	Symsize int32
+	spSize  int32
+	symSize int32
 )
 
 const (
@@ -320,7 +285,6 @@
 }
 
 var (
-	dynexp          []*sym.Symbol
 	dynlib          []string
 	ldflag          []string
 	havedynamic     int
@@ -508,7 +472,8 @@
 	default:
 		log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups)
 	}
-	ctxt.loader = loader.NewLoader(flags, elfsetstring, &ctxt.ErrorReporter.ErrorReporter)
+	elfsetstring1 := func(str string, off int) { elfsetstring(ctxt, 0, str, off) }
+	ctxt.loader = loader.NewLoader(flags, elfsetstring1, &ctxt.ErrorReporter.ErrorReporter)
 	ctxt.ErrorReporter.SymName = func(s loader.Sym) string {
 		return ctxt.loader.SymName(s)
 	}
@@ -638,15 +603,6 @@
 	strictDupMsgCount = ctxt.loader.NStrictDupMsgs()
 }
 
-// genSymsForDynexp constructs a *sym.Symbol version of ctxt.dynexp,
-// writing to the global variable 'dynexp'.
-func genSymsForDynexp(ctxt *Link) {
-	dynexp = make([]*sym.Symbol, len(ctxt.dynexp2))
-	for i, s := range ctxt.dynexp2 {
-		dynexp[i] = ctxt.loader.Syms[s]
-	}
-}
-
 // setupdynexp constructs ctxt.dynexp, a list of loader.Sym.
 func setupdynexp(ctxt *Link) {
 	dynexpMap := ctxt.cgo_export_dynamic
@@ -678,7 +634,7 @@
 		ctxt.loader.SetSymExtname(t, ctxt.loader.SymExtname(s))
 		d[i] = t
 	}
-	ctxt.dynexp2 = d
+	ctxt.dynexp = d
 
 	ctxt.cgo_export_static = nil
 	ctxt.cgo_export_dynamic = nil
@@ -777,7 +733,7 @@
 			Errorf(nil, "runtime declared tlsg variable %v", sb.Type())
 		}
 		ctxt.loader.SetAttrReachable(tlsg, true)
-		ctxt.Tlsg2 = tlsg
+		ctxt.Tlsg = tlsg
 	}
 
 	var moduledata loader.Sym
@@ -826,17 +782,7 @@
 	// the GC.
 	mdsb.SetType(sym.SNOPTRDATA)
 	ctxt.loader.SetAttrReachable(moduledata, true)
-	ctxt.Moduledata2 = 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)
-			}
-		}
-	}
+	ctxt.Moduledata = moduledata
 
 	if ctxt.Arch == sys.Arch386 && ctxt.HeadType != objabi.Hwindows {
 		if (ctxt.BuildMode == BuildModeCArchive && ctxt.IsELF) || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE || ctxt.DynlinkingGo() {
@@ -847,7 +793,7 @@
 		}
 	}
 
-	// DWARF-gen and other phases require that the unit Textp2 slices
+	// DWARF-gen and other phases require that the unit Textp slices
 	// be populated, so that it can walk the functions in each unit.
 	// Call into the loader to do this (requires that we collect the
 	// set of internal libraries first). NB: might be simpler if we
@@ -858,7 +804,7 @@
 	for _, lib := range ctxt.Library {
 		intlibs = append(intlibs, isRuntimeDepPkg(lib.Pkg))
 	}
-	ctxt.Textp2 = ctxt.loader.AssignTextSymbolOrder(ctxt.Library, intlibs, ctxt.Textp2)
+	ctxt.Textp = ctxt.loader.AssignTextSymbolOrder(ctxt.Library, intlibs, ctxt.Textp)
 }
 
 // mangleTypeSym shortens the names of symbols that represent Go types
@@ -962,67 +908,6 @@
 	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)
 
@@ -1038,21 +923,6 @@
 		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++ {
@@ -1868,32 +1738,32 @@
 	magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
 	if magic == 0x7f454c46 { // \x7F E L F
 		ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-			textp, flags, err := loadelf.Load(ctxt.loader, ctxt.Arch, ctxt.Syms.IncVersion(), f, pkg, length, pn, ehdr.flags)
+			textp, flags, err := loadelf.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn, ehdr.flags)
 			if err != nil {
 				Errorf(nil, "%v", err)
 				return
 			}
 			ehdr.flags = flags
-			ctxt.Textp2 = append(ctxt.Textp2, textp...)
+			ctxt.Textp = append(ctxt.Textp, textp...)
 		}
 		return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file)
 	}
 
 	if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe {
 		ldmacho := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-			textp, err := loadmacho.Load(ctxt.loader, ctxt.Arch, ctxt.Syms.IncVersion(), f, pkg, length, pn)
+			textp, err := loadmacho.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn)
 			if err != nil {
 				Errorf(nil, "%v", err)
 				return
 			}
-			ctxt.Textp2 = append(ctxt.Textp2, textp...)
+			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 {
 		ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-			textp, rsrc, err := loadpe.Load(ctxt.loader, ctxt.Arch, ctxt.Syms.IncVersion(), f, pkg, length, pn)
+			textp, rsrc, err := loadpe.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn)
 			if err != nil {
 				Errorf(nil, "%v", err)
 				return
@@ -1901,19 +1771,19 @@
 			if rsrc != 0 {
 				setpersrc(ctxt, rsrc)
 			}
-			ctxt.Textp2 = append(ctxt.Textp2, textp...)
+			ctxt.Textp = append(ctxt.Textp, textp...)
 		}
 		return ldhostobj(ldpe, ctxt.HeadType, f, pkg, length, pn, file)
 	}
 
 	if c1 == 0x01 && (c2 == 0xD7 || c2 == 0xF7) {
 		ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-			textp, err := loadxcoff.Load(ctxt.loader, ctxt.Arch, ctxt.Syms.IncVersion(), f, pkg, length, pn)
+			textp, err := loadxcoff.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn)
 			if err != nil {
 				Errorf(nil, "%v", err)
 				return
 			}
-			ctxt.Textp2 = append(ctxt.Textp2, textp...)
+			ctxt.Textp = append(ctxt.Textp, textp...)
 		}
 		return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file)
 	}
@@ -2000,7 +1870,7 @@
 	ldpkg(ctxt, f, lib, import1-import0-2, pn) // -2 for !\n
 	f.MustSeek(import1, 0)
 
-	fingerprint := ctxt.loader.Preload(ctxt.Syms, f, lib, unit, eof-f.Offset())
+	fingerprint := ctxt.loader.Preload(ctxt.IncVersion(), f, lib, unit, eof-f.Offset())
 	if !fingerprint.IsZero() { // Assembly objects don't have fingerprints. Ignore them.
 		// Check fingerprint, to ensure the importing and imported packages
 		// have consistent view of symbol indices.
@@ -2313,14 +2183,14 @@
 
 	// 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.Textp2 {
+	for _, s := range ctxt.Textp {
 		if ldr.IsNoSplit(s) {
 			ch.sym = s
 			sc.check(&ch, 0)
 		}
 	}
 
-	for _, s := range ctxt.Textp2 {
+	for _, s := range ctxt.Textp {
 		if !ldr.IsNoSplit(s) {
 			ch.sym = s
 			sc.check(&ch, 0)
@@ -2489,7 +2359,7 @@
 	Exit(2)
 }
 
-type SymbolType int8
+type SymbolType int8 // TODO: after genasmsym is gone, maybe rename to plan9typeChar or something
 
 const (
 	// see also https://9p.io/magic/man2html/1/nm
@@ -2506,165 +2376,7 @@
 	DeletedAutoSym = 'x'
 )
 
-func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int64)) {
-	// 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)
-		}
-	}
-
-	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)
-		}
-		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)
-		}
-	}
-
-	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.loader.Syms {
-		if s == nil {
-			continue
-		}
-		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))
-
-		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))
-
-		case sym.SUNDEFEXT:
-			if ctxt.HeadType == objabi.Hwindows || ctxt.HeadType == objabi.Haix || ctxt.IsELF {
-				put(ctxt, s, s.Name, UndefinedSym, s.Value)
-			}
-
-		case sym.SHOSTOBJ:
-			if !s.Attr.Reachable() {
-				continue
-			}
-			if ctxt.HeadType == objabi.Hwindows || ctxt.IsELF {
-				put(ctxt, s, s.Name, UndefinedSym, s.Value)
-			}
-
-		case sym.SDYNIMPORT:
-			if !s.Attr.Reachable() {
-				continue
-			}
-			put(ctxt, s, s.Extname(), UndefinedSym, 0)
-
-		case sym.STLSBSS:
-			if ctxt.LinkMode == LinkExternal {
-				put(ctxt, s, s.Name, TLSSym, Symaddr(s))
-			}
-		}
-	}
-
-	for _, s := range ctxt.Textp {
-		put(ctxt, s, s.Name, TextSym, s.Value)
-	}
-
-	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 (ctxt *Link) xdefine2(p string, t sym.SymKind, v int64) {
 	ldr := ctxt.loader
 	s := ldr.CreateSymForUpdate(p, 0)
 	s.SetType(t)
@@ -2674,14 +2386,14 @@
 	s.SetLocal(true)
 }
 
-func datoff(s *sym.Symbol, addr int64) int64 {
+func datoff(ldr *loader.Loader, s loader.Sym, 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)
+	ldr.Errorf(s, "invalid datoff %#x", addr)
 	return 0
 }
 
@@ -2690,57 +2402,16 @@
 	if a[0] >= '0' && a[0] <= '9' {
 		return atolwhex(a)
 	}
-	s := ctxt.Syms.Lookup(a, 0)
-	if s.Type == 0 {
+	ldr := ctxt.loader
+	s := ldr.Lookup(a, 0)
+	st := ldr.SymType(s)
+	if st == 0 {
 		return *FlagTextAddr
 	}
-	if ctxt.HeadType != objabi.Haix && s.Type != sym.STEXT {
-		Errorf(s, "entry not text")
+	if !ctxt.IsAIX() && st != sym.STEXT {
+		ldr.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 ctxt.datap {
-		undefsym(ctxt, s)
-	}
-	if nerrors > 0 {
-		errorexit()
-	}
+	return ldr.SymValue(s)
 }
 
 func (ctxt *Link) callgraph() {
@@ -2749,7 +2420,7 @@
 	}
 
 	ldr := ctxt.loader
-	for _, s := range ctxt.Textp2 {
+	for _, s := range ctxt.Textp {
 		relocs := ldr.Relocs(s)
 		for i := 0; i < relocs.Count(); i++ {
 			r := relocs.At2(i)
@@ -2819,143 +2490,42 @@
 	*order = append(*order, lib)
 }
 
-// addToTextp populates the context Textp slice.
-func addToTextp(ctxt *Link) {
-	// Set up ctxt.Textp, based on ctxt.Textp2.
-	textp := make([]*sym.Symbol, 0, len(ctxt.Textp2))
-	haveshlibs := len(ctxt.Shlibs) > 0
-	for _, tsym := range ctxt.Textp2 {
-		sp := ctxt.loader.Syms[tsym]
-		if sp == nil || !ctxt.loader.AttrReachable(tsym) {
-			panic("should never happen")
-		}
-		if haveshlibs && sp.Type == sym.SDYNIMPORT {
-			continue
-		}
-		textp = append(textp, sp)
-	}
-	ctxt.Textp = textp
-}
-
-func (ctxt *Link) loadlibfull(symGroupType []sym.SymKind, needReloc, needExtReloc bool) {
-	// Load full symbol contents, resolve indexed references.
-	ctxt.loader.LoadFull(ctxt.Arch, ctxt.Syms, needReloc, needExtReloc)
-
-	// Convert ctxt.Moduledata2 to ctxt.Moduledata, etc
-	if ctxt.Moduledata2 != 0 {
-		ctxt.Moduledata = ctxt.loader.Syms[ctxt.Moduledata2]
-		ctxt.Tlsg = ctxt.loader.Syms[ctxt.Tlsg2]
-	}
-
-	// Pull the symbols out.
-	ctxt.loader.ExtractSymbols(ctxt.Syms)
-	ctxt.lookup = ctxt.Syms.ROLookup
-
-	// Recreate dynexp using *sym.Symbol instead of loader.Sym
-	genSymsForDynexp(ctxt)
-
-	// Drop the cgodata reference.
-	ctxt.cgodata = nil
-
-	addToTextp(ctxt)
-
-	// Set special global symbols.
-	ctxt.setArchSyms(AfterLoadlibFull)
-
-	// Populate dwarfp from dwarfp2. If we see a symbol index
-	// whose loader.Syms entry is nil, something went wrong.
-	for _, si := range dwarfp2 {
-		syms := make([]*sym.Symbol, 0, len(si.syms))
-		for _, symIdx := range si.syms {
-			s := ctxt.loader.Syms[symIdx]
-			if s == nil {
-				panic(fmt.Sprintf("nil sym for dwarfp2 element %d", symIdx))
-			}
-			s.Attr |= sym.AttrLocal
-			syms = append(syms, s)
-		}
-		dwarfp = append(dwarfp, dwarfSecInfo2{syms: syms})
-	}
-
-	// Populate datap from datap2
-	ctxt.datap = make([]*sym.Symbol, len(ctxt.datap2))
-	for i, symIdx := range ctxt.datap2 {
-		s := ctxt.loader.Syms[symIdx]
-		if s == nil {
-			panic(fmt.Sprintf("nil sym for datap2 element %d", symIdx))
-		}
-		ctxt.datap[i] = s
-	}
-
-	// Populate the sym.Section 'Sym' fields based on their 'Sym2'
-	// fields.
-	allSegments := []*sym.Segment{&Segtext, &Segrodata, &Segrelrodata, &Segdata, &Segdwarf}
-	for _, seg := range allSegments {
-		for _, sect := range seg.Sections {
-			if sect.Sym2 != 0 {
-				s := ctxt.loader.Syms[sect.Sym2]
-				if s == nil {
-					panic(fmt.Sprintf("nil sym for sect %s sym %d", sect.Name, sect.Sym2))
-				}
-				sect.Sym = s
-			}
-		}
-	}
-
-	// For now, overwrite symbol type with its "group" type, as dodata
-	// expected. Once we converted dodata, this will probably not be
-	// needed.
-	for i, t := range symGroupType {
-		if t != sym.Sxxx {
-			s := ctxt.loader.Syms[i]
-			if s == nil {
-				continue // in dwarfcompress we drop compressed DWARF symbols
-			}
-			s.Type = t
-		}
-	}
-	symGroupType = nil
-
-	if ctxt.Debugvlog > 1 {
-		// loadlibfull is likely a good place to dump.
-		// Only dump under -v=2 and above.
-		ctxt.dumpsyms()
-	}
-}
-
-func symPkg(ctxt *Link, s *sym.Symbol) string {
-	if s == nil {
-		return ""
-	}
-	return ctxt.loader.SymPkg(loader.Sym(s.SymIdx))
-}
-
-func ElfSymForReloc(ctxt *Link, s *sym.Symbol) int32 {
+func ElfSymForReloc(ctxt *Link, s loader.Sym) int32 {
 	// If putelfsym created a local version of this symbol, use that in all
 	// relocations.
-	les := ctxt.loader.SymLocalElfSym(loader.Sym(s.SymIdx))
+	les := ctxt.loader.SymLocalElfSym(s)
 	if les != 0 {
 		return les
 	} else {
-		return ctxt.loader.SymElfSym(loader.Sym(s.SymIdx))
+		return ctxt.loader.SymElfSym(s)
 	}
 }
 
-func symSub(ctxt *Link, s *sym.Symbol) *sym.Symbol {
-	if lsub := ctxt.loader.SubSym(loader.Sym(s.SymIdx)); lsub != 0 {
-		return ctxt.loader.Syms[lsub]
+func AddGotSym(target *Target, ldr *loader.Loader, syms *ArchSyms, s loader.Sym, elfRelocTyp uint32) {
+	if ldr.SymGot(s) >= 0 {
+		return
 	}
-	return nil
-}
 
-func (ctxt *Link) dumpsyms() {
-	for _, s := range ctxt.loader.Syms {
-		if s == nil {
-			continue
+	Adddynsym(ldr, target, syms, s)
+	got := ldr.MakeSymbolUpdater(syms.GOT)
+	ldr.SetGot(s, int32(got.Size()))
+	got.AddUint(target.Arch, 0)
+
+	if target.IsElf() {
+		if target.Arch.PtrSize == 8 {
+			rela := ldr.MakeSymbolUpdater(syms.Rela)
+			rela.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
+			rela.AddUint64(target.Arch, ELF64_R_INFO(uint32(ldr.SymDynid(s)), elfRelocTyp))
+			rela.AddUint64(target.Arch, 0)
+		} else {
+			rel := ldr.MakeSymbolUpdater(syms.Rel)
+			rel.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
+			rel.AddUint32(target.Arch, ELF32_R_INFO(uint32(ldr.SymDynid(s)), elfRelocTyp))
 		}
-		fmt.Printf("%s %s reachable=%v onlist=%v outer=%v sub=%v\n", s, s.Type, s.Attr.Reachable(), s.Attr.OnList(), s.Outer, symSub(ctxt, s))
-		for i := range s.R {
-			fmt.Println("\t", s.R[i].Type, s.R[i].Sym)
-		}
+	} else if target.IsDarwin() {
+		leg := ldr.MakeSymbolUpdater(syms.LinkEditGOT)
+		leg.AddUint32(target.Arch, uint32(ldr.SymDynid(s)))
+	} else {
+		ldr.Errorf(s, "addgotsym: unsupported binary format")
 	}
 }
diff --git a/src/cmd/link/internal/ld/link.go b/src/cmd/link/internal/ld/link.go
index 435b608..9ad477e 100644
--- a/src/cmd/link/internal/ld/link.go
+++ b/src/cmd/link/internal/ld/link.go
@@ -57,7 +57,7 @@
 	outSem chan int // limits the number of output writers
 	Out    *OutBuf
 
-	Syms *sym.Symbols
+	version int // current version number for static/file-local symbols
 
 	Debugvlog int
 	Bso       *bufio.Writer
@@ -70,11 +70,9 @@
 	Library      []*sym.Library
 	LibraryByPkg map[string]*sym.Library
 	Shlibs       []Shlib
-	Textp        []*sym.Symbol
-	Textp2       []loader.Sym
+	Textp        []loader.Sym
 	NumFilesyms  int
-	Moduledata   *sym.Symbol
-	Moduledata2  loader.Sym
+	Moduledata   loader.Sym
 
 	PackageFile  map[string]string
 	PackageShlib map[string]string
@@ -90,13 +88,11 @@
 	cgo_export_static  map[string]bool
 	cgo_export_dynamic map[string]bool
 
-	datap   []*sym.Symbol
-	datap2  []loader.Sym
-	dynexp2 []loader.Sym
+	datap  []loader.Sym
+	dynexp []loader.Sym
 
 	// Elf symtab variables.
 	numelfsym int // starts at 0, 1 is reserved
-	elfbind   int
 }
 
 type cgodata struct {
@@ -137,3 +133,14 @@
 	}
 	l.Autolib = nil
 }
+
+// Allocate a new version (i.e. symbol namespace).
+func (ctxt *Link) IncVersion() int {
+	ctxt.version++
+	return ctxt.version - 1
+}
+
+// returns the maximum version number
+func (ctxt *Link) MaxVersion() int {
+	return ctxt.version
+}
diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go
index 5548b8c..c8f02c4 100644
--- a/src/cmd/link/internal/ld/macho.go
+++ b/src/cmd/link/internal/ld/macho.go
@@ -501,9 +501,8 @@
 
 	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
+		// Darwin external linker on 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")
@@ -551,7 +550,7 @@
 	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 */
+		msect.res1 = uint32(ctxt.loader.SymSize(ctxt.ArchSyms.LinkEditPLT) / 4) /* offset into indirect symbol table */
 	}
 
 	if sect.Name == ".init_array" {
@@ -575,7 +574,15 @@
 	}
 }
 
-func Asmbmacho(ctxt *Link) {
+func asmbMacho(ctxt *Link) {
+	machlink := doMachoLink(ctxt)
+	if !*FlagS && ctxt.IsExternal() {
+		symo := int64(Segdwarf.Fileoff + uint64(Rnd(int64(Segdwarf.Filelen), int64(*FlagRound))) + uint64(machlink))
+		ctxt.Out.SeekSet(symo)
+		machoEmitReloc(ctxt)
+	}
+	ctxt.Out.SeekSet(0)
+
 	/* apple MACH */
 	va := *FlagTextAddr - int64(HEADR)
 
@@ -584,10 +591,6 @@
 	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
@@ -595,10 +598,6 @@
 	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
@@ -669,12 +668,6 @@
 		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 */
@@ -688,26 +681,22 @@
 			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 {
+		ldr := ctxt.loader
+
 		// 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)
+		s1 := ldr.SymSize(ldr.Lookup(".machosymtab", 0))
+		s2 := ldr.SymSize(ctxt.ArchSyms.LinkEditPLT)
+		s3 := ldr.SymSize(ctxt.ArchSyms.LinkEditGOT)
+		s4 := ldr.SymSize(ldr.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.vsize = uint64(s1) + uint64(s2) + uint64(s3) + uint64(s4)
 			ms.fileoffset = uint64(linkoff)
 			ms.filesize = ms.vsize
 			ms.prot1 = 7
@@ -715,10 +704,10 @@
 		}
 
 		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 */
+		ml.data[0] = uint32(linkoff)                /* symoff */
+		ml.data[1] = uint32(nsortsym)               /* nsyms */
+		ml.data[2] = uint32(linkoff + s1 + s2 + s3) /* stroff */
+		ml.data[3] = uint32(s4)                     /* strsize */
 
 		machodysymtab(ctxt)
 
@@ -777,7 +766,7 @@
 	}
 
 	// Add text symbols.
-	for _, s := range ctxt.Textp2 {
+	for _, s := range ctxt.Textp {
 		addsym(s)
 	}
 
@@ -798,7 +787,7 @@
 			continue
 		}
 		t := ldr.SymType(s)
-		if t >= sym.SELFRXSECT && t < sym.SXREF || t == sym.SCONST { // data sections handled in dodata
+		if t >= sym.SELFRXSECT && t < sym.SXREF { // data sections handled in dodata
 			if t == sym.STLSBSS {
 				// TLSBSS is not used on darwin. See data.go:allocateDataSections
 				continue
@@ -845,7 +834,7 @@
 	// 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 _, s := range ctxt.dynexp2 {
+	for _, s := range ctxt.dynexp {
 		if !ldr.AttrReachable(s) {
 			panic("dynexp symbol is not reachable")
 		}
@@ -870,38 +859,39 @@
 //
 // 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() {
+func machoShouldExport(ctxt *Link, ldr *loader.Loader, s loader.Sym) bool {
+	if !ctxt.DynlinkingGo() || ldr.AttrLocal(s) {
 		return false
 	}
-	if ctxt.BuildMode == BuildModePlugin && strings.HasPrefix(s.Extname(), objabi.PathToPrefix(*flagPluginPath)) {
+	if ctxt.BuildMode == BuildModePlugin && strings.HasPrefix(ldr.SymExtname(s), objabi.PathToPrefix(*flagPluginPath)) {
 		return true
 	}
-	if strings.HasPrefix(s.Name, "go.itab.") {
+	name := ldr.RawSymName(s)
+	if strings.HasPrefix(name, "go.itab.") {
 		return true
 	}
-	if strings.HasPrefix(s.Name, "type.") && !strings.HasPrefix(s.Name, "type..") {
+	if strings.HasPrefix(name, "type.") && !strings.HasPrefix(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") {
+	if strings.HasPrefix(name, "go.link.pkghash") {
 		return true
 	}
-	return s.Type >= sym.SFirstWritable // only writable sections
+	return ldr.SymType(s) >= sym.SFirstWritable // only writable sections
 }
 
 func machosymtab(ctxt *Link) {
-	symtab := ctxt.Syms.Lookup(".machosymtab", 0)
-	symstr := ctxt.Syms.Lookup(".machosymstr", 0)
+	ldr := ctxt.loader
+	symtab := ldr.CreateSymForUpdate(".machosymtab", 0)
+	symstr := ldr.CreateSymForUpdate(".machosymstr", 0)
 
-	for i := 0; i < nsortsym; i++ {
-		s := ctxt.loader.Syms[sortsym[i]]
-		symtab.AddUint32(ctxt.Arch, uint32(symstr.Size))
+	for _, s := range sortsym[:nsortsym] {
+		symtab.AddUint32(ctxt.Arch, uint32(symstr.Size()))
 
-		export := machoShouldExport(ctxt, s)
-		isGoSymbol := strings.Contains(s.Extname(), ".")
+		export := machoShouldExport(ctxt, ldr, s)
+		isGoSymbol := strings.Contains(ldr.SymExtname(s), ".")
 
 		// In normal buildmodes, only add _ to C symbols, as
 		// Go symbols have dot in the name.
@@ -910,37 +900,37 @@
 		// 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.Name))
+		cexport := !isGoSymbol && (ctxt.BuildMode != BuildModePlugin || onlycsymbol(ldr.SymName(s)))
 		if cexport || export || isGoSymbol {
 			symstr.AddUint8('_')
 		}
 
 		// replace "·" as ".", because DTrace cannot handle it.
-		Addstring(symstr, strings.Replace(s.Extname(), "·", ".", -1))
+		symstr.Addstring(strings.Replace(ldr.SymExtname(s), "·", ".", -1))
 
-		if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ || s.Type == sym.SUNDEFEXT {
+		if t := ldr.SymType(s); t == sym.SDYNIMPORT || t == sym.SHOSTOBJ || t == 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 {
+			if ldr.AttrCgoExport(s) || export {
 				symtab.AddUint8(0x0f)
 			} else {
 				symtab.AddUint8(0x0e)
 			}
 			o := s
-			for o.Outer != nil {
-				o = o.Outer
+			if outer := ldr.OuterSym(o); outer != 0 {
+				o = outer
 			}
-			if o.Sect == nil {
-				Errorf(s, "missing section for symbol")
+			if ldr.SymSect(o) == nil {
+				ldr.Errorf(s, "missing section for symbol")
 				symtab.AddUint8(0)
 			} else {
-				symtab.AddUint8(uint8(o.Sect.Extnum))
+				symtab.AddUint8(uint8(ldr.SymSect(o).Extnum))
 			}
 			symtab.AddUint16(ctxt.Arch, 0) // desc
-			symtab.AddUintXX(ctxt.Arch, uint64(Symaddr(s)), ctxt.Arch.PtrSize)
+			symtab.AddUintXX(ctxt.Arch, uint64(ldr.SymAddr(s)), ctxt.Arch.PtrSize)
 		}
 	}
 }
@@ -967,13 +957,14 @@
 	ml.data[10] = 0 /* extrefsymoff */
 	ml.data[11] = 0 /* nextrefsyms */
 
-	// must match domacholink below
-	s1 := ctxt.Syms.Lookup(".machosymtab", 0)
+	ldr := ctxt.loader
 
-	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 */
+	// must match domacholink below
+	s1 := ldr.SymSize(ldr.Lookup(".machosymtab", 0))
+	s2 := ldr.SymSize(ctxt.ArchSyms.LinkEditPLT)
+	s3 := ldr.SymSize(ctxt.ArchSyms.LinkEditGOT)
+	ml.data[12] = uint32(linkoff + s1)  /* indirectsymoff */
+	ml.data[13] = uint32((s2 + s3) / 4) /* nindirectsyms */
 
 	ml.data[14] = 0 /* extreloff */
 	ml.data[15] = 0 /* nextrel */
@@ -981,15 +972,16 @@
 	ml.data[17] = 0 /* nlocrel */
 }
 
-func Domacholink(ctxt *Link) int64 {
+func doMachoLink(ctxt *Link) int64 {
 	machosymtab(ctxt)
 
-	// write data that will be linkedit section
-	s1 := ctxt.Syms.Lookup(".machosymtab", 0)
+	ldr := ctxt.loader
 
-	s2 := ctxt.Syms.Lookup(".linkedit.plt", 0)
-	s3 := ctxt.Syms.Lookup(".linkedit.got", 0)
-	s4 := ctxt.Syms.Lookup(".machosymstr", 0)
+	// write data that will be linkedit section
+	s1 := ldr.Lookup(".machosymtab", 0)
+	s2 := ctxt.ArchSyms.LinkEditPLT
+	s3 := ctxt.ArchSyms.LinkEditGOT
+	s4 := ldr.Lookup(".machosymstr", 0)
 
 	// Force the linkedit section to end on a 16-byte
 	// boundary. This allows pure (non-cgo) Go binaries
@@ -1008,26 +1000,27 @@
 	// boundary, codesign_allocate will not need to apply
 	// any alignment padding itself, working around the
 	// issue.
-	for s4.Size%16 != 0 {
-		s4.AddUint8(0)
+	s4b := ldr.MakeSymbolUpdater(s4)
+	for s4b.Size()%16 != 0 {
+		s4b.AddUint8(0)
 	}
 
-	size := int(s1.Size + s2.Size + s3.Size + s4.Size)
+	size := int(ldr.SymSize(s1) + ldr.SymSize(s2) + ldr.SymSize(s3) + ldr.SymSize(s4))
 
 	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])
+		ctxt.Out.Write(ldr.Data(s1))
+		ctxt.Out.Write(ldr.Data(s2))
+		ctxt.Out.Write(ldr.Data(s3))
+		ctxt.Out.Write(ldr.Data(s4))
 	}
 
 	return Rnd(int64(size), int64(*FlagRound))
 }
 
-func machorelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) {
+func machorelocsect(ctxt *Link, ldr *loader.Loader, sect *sym.Section, syms []loader.Sym) {
 	// If main section has no bits, nothing to relocate.
 	if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
 		return
@@ -1035,10 +1028,10 @@
 
 	sect.Reloff = uint64(ctxt.Out.Offset())
 	for i, s := range syms {
-		if !s.Attr.Reachable() {
+		if !ldr.AttrReachable(s) {
 			continue
 		}
-		if uint64(s.Value) >= sect.Vaddr {
+		if uint64(ldr.SymValue(s)) >= sect.Vaddr {
 			syms = syms[i:]
 			break
 		}
@@ -1046,26 +1039,24 @@
 
 	eaddr := int32(sect.Vaddr + sect.Length)
 	for _, s := range syms {
-		if !s.Attr.Reachable() {
+		if !ldr.AttrReachable(s) {
 			continue
 		}
-		if s.Value >= int64(eaddr) {
+		if ldr.SymValue(s) >= int64(eaddr) {
 			break
 		}
-		for ri := range s.R {
-			r := &s.R[ri]
-			if r.Done {
+		relocs := ldr.ExtRelocs(s)
+		for ri := 0; ri < relocs.Count(); ri++ {
+			r := relocs.At(ri)
+			if r.Xsym == 0 {
+				ldr.Errorf(s, "missing xsym in relocation")
 				continue
 			}
-			if r.Xsym == nil {
-				Errorf(s, "missing xsym in relocation")
-				continue
+			if !ldr.AttrReachable(r.Xsym) {
+				ldr.Errorf(s, "unreachable reloc %d (%s) target %v", r.Type(), sym.RelocName(ctxt.Arch, r.Type()), ldr.SymName(r.Xsym))
 			}
-			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)
+			if !thearch.Machoreloc1(ctxt.Arch, ctxt.Out, ldr, s, r, int64(uint64(ldr.SymValue(s)+int64(r.Off()))-sect.Vaddr)) {
+				ldr.Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type(), sym.RelocName(ctxt.Arch, r.Type()), r.Siz(), ldr.SymName(r.Sym()))
 			}
 		}
 	}
@@ -1073,26 +1064,27 @@
 	sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
 }
 
-func Machoemitreloc(ctxt *Link) {
+func machoEmitReloc(ctxt *Link) {
 	for ctxt.Out.Offset()&7 != 0 {
 		ctxt.Out.Write8(0)
 	}
 
-	machorelocsect(ctxt, Segtext.Sections[0], ctxt.Textp)
+	ldr := ctxt.loader
+	machorelocsect(ctxt, ldr, Segtext.Sections[0], ctxt.Textp)
 	for _, sect := range Segtext.Sections[1:] {
-		machorelocsect(ctxt, sect, ctxt.datap)
+		machorelocsect(ctxt, ldr, sect, ctxt.datap)
 	}
 	for _, sect := range Segdata.Sections {
-		machorelocsect(ctxt, sect, ctxt.datap)
+		machorelocsect(ctxt, ldr, sect, ctxt.datap)
 	}
 	for i := 0; i < len(Segdwarf.Sections); i++ {
 		sect := Segdwarf.Sections[i]
 		si := dwarfp[i]
-		if si.secSym() != sect.Sym ||
-			si.secSym().Sect != sect {
+		if si.secSym() != loader.Sym(sect.Sym) ||
+			ctxt.loader.SymSect(si.secSym()) != sect {
 			panic("inconsistency between dwarfp and Segdwarf")
 		}
-		machorelocsect(ctxt, sect, si.syms)
+		machorelocsect(ctxt, ldr, sect, si.syms)
 	}
 }
 
diff --git a/src/cmd/link/internal/ld/main.go b/src/cmd/link/internal/ld/main.go
index 2738c8a..e68997f 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"
@@ -83,9 +82,8 @@
 	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
+	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).")
@@ -99,8 +97,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.
@@ -124,7 +120,7 @@
 
 	// 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")
+		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")
@@ -140,10 +136,6 @@
 
 	objabi.Flagparse(usage)
 
-	if !*flagGo115Newobj {
-		oldlink()
-	}
-
 	switch *flagHeadType {
 	case "":
 	case "windowsgui":
@@ -279,10 +271,10 @@
 	ctxt.textbuildid()
 	bench.Start("addexport")
 	setupdynexp(ctxt)
-	ctxt.setArchSyms(BeforeLoadlibFull)
+	ctxt.setArchSyms()
 	ctxt.addexport()
 	bench.Start("Gentext")
-	thearch.Gentext2(ctxt, ctxt.loader) // trampolines, call stubs, etc.
+	thearch.Gentext(ctxt, ctxt.loader) // trampolines, call stubs, etc.
 
 	bench.Start("textaddress")
 	ctxt.textaddress()
@@ -299,7 +291,7 @@
 	bench.Start("symtab")
 	symGroupType := ctxt.symtab()
 	bench.Start("dodata")
-	ctxt.dodata2(symGroupType)
+	ctxt.dodata(symGroupType)
 	bench.Start("address")
 	order := ctxt.address()
 	bench.Start("dwarfcompress")
@@ -320,43 +312,23 @@
 			panic(err)
 		}
 	}
-	// Asmb will redirect symbols to the output file mmap, and relocations
+	// asmb will redirect symbols to the output file mmap, and relocations
 	// will be applied directly there.
 	bench.Start("Asmb")
 	ctxt.loader.InitOutData()
-	thearch.Asmb(ctxt, ctxt.loader)
-
-	newreloc := ctxt.IsAMD64() || ctxt.Is386() || ctxt.IsWasm()
-	if newreloc {
-		bench.Start("reloc")
-		ctxt.reloc()
-		bench.Start("loadlibfull")
-		// We don't need relocations at this point.
-		// An exception is internal linking on Windows, see pe.go:addPEBaseRelocSym
-		// Wasm is another exception, where it applies text relocations in Asmb2.
-		needReloc := (ctxt.IsWindows() && ctxt.IsInternal()) || ctxt.IsWasm()
-		// On AMD64 ELF, we directly use the loader's ExtRelocs, so we don't
-		// need conversion. Otherwise we do.
-		needExtReloc := ctxt.IsExternal() && !(ctxt.IsAMD64() && ctxt.IsELF)
-		ctxt.loadlibfull(symGroupType, needReloc, needExtReloc) // XXX do it here for now
-	} else {
-		bench.Start("loadlibfull")
-		ctxt.loadlibfull(symGroupType, true, false) // XXX do it here for now
-		bench.Start("reloc")
-		ctxt.reloc2()
-	}
+	asmb(ctxt, ctxt.loader)
+	bench.Start("reloc")
+	ctxt.reloc()
 	bench.Start("Asmb2")
-	thearch.Asmb2(ctxt)
+	asmb2(ctxt)
 
 	bench.Start("Munmap")
 	ctxt.Out.Close() // Close handles Munmapping if necessary.
 
-	bench.Start("undef")
-	ctxt.undef()
 	bench.Start("hostlink")
 	ctxt.hostlink()
 	if ctxt.Debugvlog != 0 {
-		ctxt.Logf("%d symbols, %d reachable\n", len(ctxt.loader.Syms), ctxt.loader.NReachableSym())
+		ctxt.Logf("%d symbols, %d reachable\n", ctxt.loader.NSym(), ctxt.loader.NReachableSym())
 		ctxt.Logf("%d liveness data\n", liveness)
 	}
 	bench.Start("Flush")
@@ -415,48 +387,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/ld/outbuf_mmap.go b/src/cmd/link/internal/ld/outbuf_mmap.go
index e2e50cc84..41c436e 100644
--- a/src/cmd/link/internal/ld/outbuf_mmap.go
+++ b/src/cmd/link/internal/ld/outbuf_mmap.go
@@ -2,7 +2,7 @@
 // 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
+// +build aix darwin dragonfly freebsd linux netbsd openbsd
 
 package ld
 
diff --git a/src/cmd/link/internal/ld/outbuf_nommap.go b/src/cmd/link/internal/ld/outbuf_nommap.go
index 51218d8..bad01dc 100644
--- a/src/cmd/link/internal/ld/outbuf_nommap.go
+++ b/src/cmd/link/internal/ld/outbuf_nommap.go
@@ -2,7 +2,7 @@
 // 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
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!windows
 
 package ld
 
diff --git a/src/cmd/link/internal/ld/outbuf_test.go b/src/cmd/link/internal/ld/outbuf_test.go
index d8c2142..db0a924 100644
--- a/src/cmd/link/internal/ld/outbuf_test.go
+++ b/src/cmd/link/internal/ld/outbuf_test.go
@@ -17,7 +17,7 @@
 	switch runtime.GOOS {
 	default:
 		t.Skip("unsupported OS")
-	case "darwin", "dragonfly", "freebsd", "linux", "openbsd", "windows":
+	case "aix", "darwin", "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "windows":
 	}
 	dir, err := ioutil.TempDir("", "TestMMap")
 	if err != nil {
diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go
index 5cbb7bb..a5f776e 100644
--- a/src/cmd/link/internal/ld/pcln.go
+++ b/src/cmd/link/internal/ld/pcln.go
@@ -259,7 +259,7 @@
 	//	offset to file table [4 bytes]
 
 	// Find container symbols and mark them as such.
-	for _, s := range ctxt.Textp2 {
+	for _, s := range ctxt.Textp {
 		outer := ldr.OuterSym(s)
 		if outer != 0 {
 			state.container.Set(outer)
@@ -268,8 +268,8 @@
 
 	// Gather some basic stats and info.
 	var nfunc int32
-	prevSect := ldr.SymSect(ctxt.Textp2[0])
-	for _, s := range ctxt.Textp2 {
+	prevSect := ldr.SymSect(ctxt.Textp[0])
+	for _, s := range ctxt.Textp {
 		if !emitPcln(ctxt, s, state.container) {
 			continue
 		}
@@ -297,7 +297,7 @@
 	ftab.SetUint(ctxt.Arch, 8, uint64(nfunc))
 	pclntabPclntabOffset = int32(8 + ctxt.Arch.PtrSize)
 
-	szHint := len(ctxt.Textp2) * 2
+	szHint := len(ctxt.Textp) * 2
 	funcnameoff := make(map[string]int32, szHint)
 	nameToOffset := func(name string) int32 {
 		nameoff, ok := funcnameoff[name]
@@ -350,8 +350,8 @@
 	funcdataoff := []int64{}
 
 	nfunc = 0 // repurpose nfunc as a running index
-	prevFunc := ctxt.Textp2[0]
-	for _, s := range ctxt.Textp2 {
+	prevFunc := ctxt.Textp[0]
+	for _, s := range ctxt.Textp {
 		if !emitPcln(ctxt, s, state.container) {
 			continue
 		}
@@ -524,7 +524,7 @@
 		nfunc++
 	}
 
-	last := ctxt.Textp2[len(ctxt.Textp2)-1]
+	last := ctxt.Textp[len(ctxt.Textp)-1]
 	pclntabLastFunc = last
 	// Final entry of table is just end pc.
 	setAddr(ftab, ctxt.Arch, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize), last, ldr.SymSize(last))
@@ -592,8 +592,8 @@
 	ldr.SetAttrLocal(tsym, true)
 
 	// find min and max address
-	min := ldr.SymValue(ctxt.Textp2[0])
-	lastp := ctxt.Textp2[len(ctxt.Textp2)-1]
+	min := ldr.SymValue(ctxt.Textp[0])
+	lastp := ctxt.Textp[len(ctxt.Textp)-1]
 	max := ldr.SymValue(lastp) + ldr.SymSize(lastp)
 
 	// for each subbucket, compute the minimum of all symbol indexes
@@ -605,18 +605,18 @@
 		indexes[i] = NOIDX
 	}
 	idx := int32(0)
-	for i, s := range ctxt.Textp2 {
+	for i, s := range ctxt.Textp {
 		if !emitPcln(ctxt, s, container) {
 			continue
 		}
 		p := ldr.SymValue(s)
 		var e loader.Sym
 		i++
-		if i < len(ctxt.Textp2) {
-			e = ctxt.Textp2[i]
+		if i < len(ctxt.Textp) {
+			e = ctxt.Textp[i]
 		}
-		for e != 0 && !emitPcln(ctxt, e, container) && i < len(ctxt.Textp2) {
-			e = ctxt.Textp2[i]
+		for e != 0 && !emitPcln(ctxt, e, container) && i < len(ctxt.Textp) {
+			e = ctxt.Textp[i]
 			i++
 		}
 		q := max
diff --git a/src/cmd/link/internal/ld/pe.go b/src/cmd/link/internal/ld/pe.go
index 362d2fd..f0211e1 100644
--- a/src/cmd/link/internal/ld/pe.go
+++ b/src/cmd/link/internal/ld/pe.go
@@ -472,8 +472,8 @@
 	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
+	init_entry := ctxt.loader.Lookup(*flagEntrySymbol, 0)
+	addr := uint64(ctxt.loader.SymValue(init_entry)) - ctxt.loader.SymSect(init_entry).Vaddr
 	switch objabi.GOARCH {
 	case "386", "arm":
 		ctxt.Out.Write32(uint32(addr))
@@ -489,58 +489,58 @@
 		ctxt.Out.Write8(0)
 	}
 
+	ldr := ctxt.loader
+
 	// 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 {
+	relocsect := func(sect *sym.Section, syms []loader.Sym, 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
+		nrelocs := 0
 		sect.Reloff = uint64(ctxt.Out.Offset())
 		for i, s := range syms {
-			if !s.Attr.Reachable() {
+			if !ldr.AttrReachable(s) {
 				continue
 			}
-			if uint64(s.Value) >= sect.Vaddr {
+			if uint64(ldr.SymValue(s)) >= sect.Vaddr {
 				syms = syms[i:]
 				break
 			}
 		}
 		eaddr := int32(sect.Vaddr + sect.Length)
-		for _, sym := range syms {
-			if !sym.Attr.Reachable() {
+		for _, s := range syms {
+			if !ldr.AttrReachable(s) {
 				continue
 			}
-			if sym.Value >= int64(eaddr) {
+			if ldr.SymValue(s) >= int64(eaddr) {
 				break
 			}
-			for ri := range sym.R {
-				r := &sym.R[ri]
-				if r.Done {
+			relocs := ldr.ExtRelocs(s)
+			for ri := 0; ri < relocs.Count(); ri++ {
+				r := relocs.At(ri)
+				if r.Xsym == 0 {
+					ctxt.Errorf(s, "missing xsym in relocation")
 					continue
 				}
-				if r.Xsym == nil {
-					Errorf(sym, "missing xsym in relocation")
-					continue
+				if ldr.SymDynid(r.Xsym) < 0 {
+					ctxt.Errorf(s, "reloc %d to non-coff symbol %s (outer=%s) %d", r.Type(), ldr.SymName(r.Sym()), ldr.SymName(r.Xsym), ldr.SymType(r.Sym()))
 				}
-				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, ldr, s, r, int64(uint64(ldr.SymValue(s)+int64(r.Off()))-base)) {
+					ctxt.Errorf(s, "unsupported obj reloc %d/%d to %s", r.Type(), r.Siz(), ldr.SymName(r.Sym()))
 				}
-				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++
+				nrelocs++
 			}
 		}
 		sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
-		return relocs
+		return nrelocs
 	}
 
 	sects := []struct {
 		peSect *peSection
 		seg    *sym.Segment
-		syms   []*sym.Symbol
+		syms   []loader.Sym
 	}{
 		{f.textSect, &Segtext, ctxt.Textp},
 		{f.rdataSect, &Segrodata, ctxt.datap},
@@ -560,8 +560,8 @@
 	for i := 0; i < len(Segdwarf.Sections); i++ {
 		sect := Segdwarf.Sections[i]
 		si := dwarfp[i]
-		if si.secSym() != sect.Sym ||
-			si.secSym().Sect != sect {
+		if si.secSym() != loader.Sym(sect.Sym) ||
+			ldr.SymSect(si.secSym()) != sect {
 			panic("inconsistency between dwarfp and Segdwarf")
 		}
 		for _, pesect := range f.sections {
@@ -576,12 +576,12 @@
 	}
 
 	f.ctorsSect.emitRelocations(ctxt.Out, func() int {
-		dottext := ctxt.Syms.Lookup(".text", 0)
+		dottext := ldr.Lookup(".text", 0)
 		ctxt.Out.Write32(0)
-		ctxt.Out.Write32(uint32(dottext.Dynid))
+		ctxt.Out.Write32(uint32(ldr.SymDynid(dottext)))
 		switch objabi.GOARCH {
 		default:
-			Errorf(dottext, "unknown architecture for PE: %q\n", objabi.GOARCH)
+			ctxt.Errorf(dottext, "unknown architecture for PE: %q\n", objabi.GOARCH)
 		case "386":
 			ctxt.Out.Write16(IMAGE_REL_I386_DIR32)
 		case "amd64":
@@ -595,12 +595,12 @@
 
 // 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 {
+func (f *peFile) writeSymbol(out *OutBuf, ldr *loader.Loader, s loader.Sym, name string, value int64, sectidx int, typ uint16, class uint8) {
+	if len(name) > 8 {
 		out.Write32(0)
-		out.Write32(uint32(f.stringTable.add(s.Name)))
+		out.Write32(uint32(f.stringTable.add(name)))
 	} else {
-		out.WriteStringN(s.Name, 8)
+		out.WriteStringN(name, 8)
 	}
 	out.Write32(uint32(value))
 	out.Write16(uint16(sectidx))
@@ -608,31 +608,32 @@
 	out.Write8(class)
 	out.Write8(0) // no aux entries
 
-	s.Dynid = int32(f.symbolCount)
+	ldr.SetSymDynid(s, 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)
+func (f *peFile) mapToPESection(ldr *loader.Loader, s loader.Sym, linkmode LinkMode) (pesectidx int, offset int64, err error) {
+	sect := ldr.SymSect(s)
+	if sect == nil {
+		return 0, 0, fmt.Errorf("could not map %s symbol with no section", ldr.SymName(s))
 	}
-	if s.Sect.Seg == &Segtext {
-		return f.textSect.index, int64(uint64(s.Value) - Segtext.Vaddr), nil
+	if sect.Seg == &Segtext {
+		return f.textSect.index, int64(uint64(ldr.SymValue(s)) - Segtext.Vaddr), nil
 	}
-	if s.Sect.Seg == &Segrodata {
-		return f.rdataSect.index, int64(uint64(s.Value) - Segrodata.Vaddr), nil
+	if sect.Seg == &Segrodata {
+		return f.rdataSect.index, int64(uint64(ldr.SymValue(s)) - 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)
+	if sect.Seg != &Segdata {
+		return 0, 0, fmt.Errorf("could not map %s symbol with non .text or .rdata or .data section", ldr.SymName(s))
 	}
-	v := uint64(s.Value) - Segdata.Vaddr
+	v := uint64(ldr.SymValue(s)) - Segdata.Vaddr
 	if linkmode != LinkExternal {
 		return f.dataSect.index, int64(v), nil
 	}
-	if s.Type == sym.SDATA {
+	if ldr.SymType(s) == 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
@@ -645,60 +646,100 @@
 
 // writeSymbols writes all COFF symbol table records.
 func (f *peFile) writeSymbols(ctxt *Link) {
+	ldr := ctxt.loader
+	addsym := func(s loader.Sym) {
+		t := ldr.SymType(s)
+		if ldr.SymSect(s) == nil && t != sym.SDYNIMPORT && t != sym.SHOSTOBJ && t != sym.SUNDEFEXT {
+			return
+		}
 
-	put := func(ctxt *Link, s *sym.Symbol, name string, type_ SymbolType, addr int64) {
-		if s == nil {
-			return
-		}
-		if s.Sect == nil && type_ != UndefinedSym {
-			return
-		}
-		switch type_ {
-		default:
-			return
-		case DataSym, BSSSym, TextSym, UndefinedSym:
-		}
+		name := ldr.SymName(s)
 
 		// 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
+		if ctxt.Is386() && ctxt.IsExternal() &&
+			(t == sym.SHOSTOBJ || t == sym.SUNDEFEXT || ldr.AttrCgoExport(s)) {
+			name = "_" + name
 		}
 
-		var typ uint16
-		if ctxt.LinkMode == LinkExternal {
-			typ = IMAGE_SYM_TYPE_NULL
+		var peSymType uint16
+		if ctxt.IsExternal() {
+			peSymType = 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"
+			// peSymType = IMAGE_SYM_DTYPE_ARRAY<<8 + IMAGE_SYM_TYPE_STRUCT
+			peSymType = 0x0308 // "array of structs"
 		}
-		sect, value, err := f.mapToPESection(s, ctxt.LinkMode)
+		sect, value, err := f.mapToPESection(ldr, s, ctxt.LinkMode)
 		if err != nil {
-			if type_ == UndefinedSym {
-				typ = IMAGE_SYM_DTYPE_FUNCTION
+			if t == sym.SDYNIMPORT || t == sym.SHOSTOBJ || t == sym.SUNDEFEXT {
+				peSymType = IMAGE_SYM_DTYPE_FUNCTION
 			} else {
-				Errorf(s, "addpesym: %v", err)
+				ctxt.Errorf(s, "addpesym: %v", err)
 			}
 		}
 		class := IMAGE_SYM_CLASS_EXTERNAL
-		if s.IsFileLocal() || s.Attr.VisibilityHidden() || s.Attr.Local() {
+		if ldr.IsFileLocal(s) || ldr.AttrVisibilityHidden(s) || ldr.AttrLocal(s) {
 			class = IMAGE_SYM_CLASS_STATIC
 		}
-		f.writeSymbol(ctxt.Out, s, value, sect, typ, uint8(class))
+		f.writeSymbol(ctxt.Out, ldr, s, name, value, sect, peSymType, 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)
+			s := ldr.LookupOrCreateSym(pesect.name, 0)
+			f.writeSymbol(ctxt.Out, ldr, s, pesect.name, 0, pesect.index, IMAGE_SYM_TYPE_NULL, IMAGE_SYM_CLASS_STATIC)
 		}
 	}
 
-	genasmsym(ctxt, put)
+	// Add special runtime.text and runtime.etext symbols.
+	s := ldr.Lookup("runtime.text", 0)
+	if ldr.SymType(s) == sym.STEXT {
+		addsym(s)
+	}
+	s = ldr.Lookup("runtime.etext", 0)
+	if ldr.SymType(s) == sym.STEXT {
+		addsym(s)
+	}
+
+	// Add text symbols.
+	for _, s := range ctxt.Textp {
+		addsym(s)
+	}
+
+	shouldBeInSymbolTable := func(s loader.Sym) bool {
+		if ldr.AttrNotInSymbolTable(s) {
+			return false
+		}
+		name := ldr.RawSymName(s) // TODO: try not to read the name
+		if name == "" || name[0] == '.' {
+			return false
+		}
+		return true
+	}
+
+	// Add data symbols and external references.
+	for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
+		if !ldr.AttrReachable(s) {
+			continue
+		}
+		t := ldr.SymType(s)
+		if t >= sym.SELFRXSECT && t < sym.SXREF { // data sections handled in dodata
+			if t == sym.STLSBSS {
+				continue
+			}
+			if !shouldBeInSymbolTable(s) {
+				continue
+			}
+			addsym(s)
+		}
+
+		switch t {
+		case sym.SDYNIMPORT, sym.SHOSTOBJ, sym.SUNDEFEXT:
+			addsym(s)
+		}
+	}
 }
 
 // writeSymbolTableAndStringTable writes out symbol and string tables for peFile f.
@@ -1109,7 +1150,7 @@
 func addimports(ctxt *Link, datsect *peSection) {
 	ldr := ctxt.loader
 	startoff := ctxt.Out.Offset()
-	dynamic := ctxt.Syms.Lookup(".windynamic", 0)
+	dynamic := ldr.LookupOrCreateSym(".windynamic", 0)
 
 	// skip import descriptor table (will write it later)
 	n := uint64(0)
@@ -1130,7 +1171,7 @@
 		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, ldr.Syms[m.s].Extname())
+			strput(ctxt.Out, ldr.SymExtname(m.s))
 		}
 	}
 
@@ -1165,7 +1206,7 @@
 	endoff := ctxt.Out.Offset()
 
 	// write FirstThunks (allocated in .data section)
-	ftbase := uint64(dynamic.Value) - uint64(datsect.virtualAddress) - PEBASE
+	ftbase := uint64(ldr.SymValue(dynamic)) - uint64(datsect.virtualAddress) - PEBASE
 
 	ctxt.Out.SeekSet(int64(uint64(datsect.pointerToRawData) + ftbase))
 	for d := dr; d != nil; d = d.next {
@@ -1205,8 +1246,8 @@
 	// 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)
+	pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = uint32(ldr.SymValue(dynamic) - PEBASE)
+	pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_IAT].Size = uint32(ldr.SymSize(dynamic))
 
 	out.SeekSet(endoff)
 }
@@ -1235,7 +1276,7 @@
 	nexport := len(dexport)
 	size := binary.Size(&e) + 10*nexport + len(*flagOutfile) + 1
 	for _, s := range dexport {
-		size += len(ldr.Syms[s].Extname()) + 1
+		size += len(ldr.SymExtname(s)) + 1
 	}
 
 	if nexport == 0 {
@@ -1271,7 +1312,7 @@
 
 	// put EXPORT Address Table
 	for _, s := range dexport {
-		out.Write32(uint32(ldr.Syms[s].Value - PEBASE))
+		out.Write32(uint32(ldr.SymValue(s) - PEBASE))
 	}
 
 	// put EXPORT Name Pointer Table
@@ -1279,7 +1320,7 @@
 
 	for _, s := range dexport {
 		out.Write32(uint32(v))
-		v += len(ldr.Syms[s].Extname()) + 1
+		v += len(ldr.SymExtname(s)) + 1
 	}
 
 	// put EXPORT Ordinal Table
@@ -1291,8 +1332,8 @@
 	out.WriteStringN(*flagOutfile, len(*flagOutfile)+1)
 
 	for _, s := range dexport {
-		ss := ldr.Syms[s]
-		out.WriteStringN(ss.Extname(), len(ss.Extname())+1)
+		name := ldr.SymExtname(s)
+		out.WriteStringN(name, len(name)+1)
 	}
 	sect.pad(out, uint32(size))
 }
@@ -1300,8 +1341,6 @@
 // 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
@@ -1338,13 +1377,13 @@
 	rt.blocks = make(map[uint32]peBaseRelocBlock)
 }
 
-func (rt *peBaseRelocTable) addentry(ctxt *Link, s *sym.Symbol, r *sym.Reloc) {
+func (rt *peBaseRelocTable) addentry(ldr *loader.Loader, s loader.Sym, r *loader.Reloc2) {
 	// 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)
+	addr := ldr.SymValue(s) + int64(r.Off()) - int64(PEBASE)
 	page := uint32(addr &^ pageMask)
 	off := uint32(addr & pageMask)
 
@@ -1355,12 +1394,10 @@
 
 	e := peBaseRelocEntry{
 		typeOff: uint16(off & 0xFFF),
-		rel:     r,
-		sym:     s,
 	}
 
 	// Set entry type
-	switch r.Siz {
+	switch r.Siz() {
 	default:
 		Exitf("unsupported relocation size %d\n", r.Siz)
 	case 4:
@@ -1392,30 +1429,32 @@
 	}
 }
 
-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 {
+func addPEBaseRelocSym(ldr *loader.Loader, s loader.Sym, rt *peBaseRelocTable) {
+	relocs := ldr.Relocs(s)
+	for ri := 0; ri < relocs.Count(); ri++ {
+		r := relocs.At2(ri)
+		if r.Type() >= objabi.ElfRelocOffset {
 			continue
 		}
-		if !r.Sym.Attr.Reachable() {
+		if r.Siz() == 0 { // informational relocation
 			continue
 		}
-		if r.Type >= objabi.ElfRelocOffset {
+		if r.Type() == objabi.R_DWARFFILEREF {
 			continue
 		}
-		if r.Siz == 0 { // informational relocation
+		rs := r.Sym()
+		rs = ldr.ResolveABIAlias(rs)
+		if rs == 0 {
 			continue
 		}
-		if r.Type == objabi.R_DWARFFILEREF {
+		if !ldr.AttrReachable(s) {
 			continue
 		}
 
-		switch r.Type {
+		switch r.Type() {
 		default:
 		case objabi.R_ADDR:
-			rt.addentry(ctxt, s, r)
+			rt.addentry(ldr, s, &r)
 		}
 	}
 }
@@ -1437,11 +1476,12 @@
 	rt.init(ctxt)
 
 	// Get relocation information
+	ldr := ctxt.loader
 	for _, s := range ctxt.Textp {
-		addPEBaseRelocSym(ctxt, s, &rt)
+		addPEBaseRelocSym(ldr, s, &rt)
 	}
 	for _, s := range ctxt.datap {
-		addPEBaseRelocSym(ctxt, s, &rt)
+		addPEBaseRelocSym(ldr, s, &rt)
 	}
 
 	// Write relocation information
@@ -1507,7 +1547,7 @@
 	pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = h.virtualSize
 }
 
-func Asmbpe(ctxt *Link) {
+func asmbPe(ctxt *Link) {
 	switch ctxt.Arch.Family {
 	default:
 		Exitf("unknown PE architecture: %v", ctxt.Arch.Family)
diff --git a/src/cmd/link/internal/ld/sym.go b/src/cmd/link/internal/ld/sym.go
index 1b7d9d5..3f26945 100644
--- a/src/cmd/link/internal/ld/sym.go
+++ b/src/cmd/link/internal/ld/sym.go
@@ -44,7 +44,7 @@
 	ler := loader.ErrorReporter{AfterErrorAction: afterErrorAction}
 	ctxt := &Link{
 		Target:        Target{Arch: arch},
-		Syms:          sym.NewSymbols(),
+		version:       sym.SymVerStatic,
 		outSem:        make(chan int, 2*runtime.GOMAXPROCS(0)),
 		Out:           NewOutBuf(arch),
 		LibraryByPkg:  make(map[string]*sym.Library),
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
index 46aa33b..577c24e 100644
--- a/src/cmd/link/internal/ld/symtab.go
+++ b/src/cmd/link/internal/ld/symtab.go
@@ -32,7 +32,6 @@
 
 import (
 	"cmd/internal/objabi"
-	"cmd/internal/sys"
 	"cmd/link/internal/loader"
 	"cmd/link/internal/sym"
 	"fmt"
@@ -62,7 +61,7 @@
 		out.Write16(uint16(shndx))
 		out.Write64(uint64(addr))
 		out.Write64(uint64(size))
-		Symsize += ELF64SYMSIZE
+		symSize += ELF64SYMSIZE
 	} else {
 		out.Write32(uint32(off))
 		out.Write32(uint32(addr))
@@ -70,62 +69,42 @@
 		out.Write8(uint8(info))
 		out.Write8(uint8(other))
 		out.Write16(uint16(shndx))
-		Symsize += ELF32SYMSIZE
+		symSize += ELF32SYMSIZE
 	}
 }
 
-func putelfsym(ctxt *Link, x *sym.Symbol, s string, t SymbolType, addr int64) {
-	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
-	}
+func putelfsym(ctxt *Link, x loader.Sym, typ int, curbind int) {
+	ldr := ctxt.loader
+	addr := ldr.SymValue(x)
+	size := ldr.SymSize(x)
 
 	xo := x
-	for xo.Outer != nil {
-		xo = xo.Outer
+	if ldr.OuterSym(x) != 0 {
+		xo = ldr.OuterSym(x)
 	}
+	xot := ldr.SymType(xo)
+	xosect := ldr.SymSect(xo)
 
 	var elfshnum int
-	if xo.Type == sym.SDYNIMPORT || xo.Type == sym.SHOSTOBJ || xo.Type == sym.SUNDEFEXT {
+	if xot == sym.SDYNIMPORT || xot == sym.SHOSTOBJ || xot == sym.SUNDEFEXT {
 		elfshnum = SHN_UNDEF
+		size = 0
 	} else {
-		if xo.Sect == nil {
-			Errorf(x, "missing section in putelfsym")
+		if xosect == nil {
+			ldr.Errorf(x, "missing section in putelfsym")
 			return
 		}
-		if xo.Sect.Elfsect == nil {
-			Errorf(x, "missing ELF section in putelfsym")
+		if xosect.Elfsect == nil {
+			ldr.Errorf(x, "missing ELF section in putelfsym")
 			return
 		}
-		elfshnum = xo.Sect.Elfsect.(*ElfShdr).shnum
+		elfshnum = xosect.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() {
+	if ldr.IsFileLocal(x) || ldr.AttrVisibilityHidden(x) || ldr.AttrLocal(x) {
 		bind = STB_LOCAL
 	}
 
@@ -134,15 +113,15 @@
 	// 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 {
+	if !ctxt.DynlinkingGo() && ctxt.IsExternal() && !ldr.AttrCgoExportStatic(x) && elfshnum != SHN_UNDEF {
 		bind = STB_LOCAL
 	}
 
 	if ctxt.LinkMode == LinkExternal && elfshnum != SHN_UNDEF {
-		addr -= int64(xo.Sect.Vaddr)
+		addr -= int64(xosect.Vaddr)
 	}
 	other := STV_DEFAULT
-	if x.Attr.VisibilityHidden() {
+	if ldr.AttrVisibilityHidden(x) {
 		// 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
@@ -150,7 +129,7 @@
 		// 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" {
+	if ctxt.IsPPC64() && typ == STT_FUNC && ldr.AttrShared(x) && ldr.SymName(x) != "runtime.duffzero" && ldr.SymName(x) != "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.
@@ -160,22 +139,17 @@
 		other |= 3 << 5
 	}
 
-	if s == x.Name {
-		// We should use Extname for ELF symbol table.
-		// TODO: maybe genasmsym should have done this. That function is too
-		// overloaded and I would rather not change it for now.
-		s = x.Extname()
-	}
+	sname := ldr.SymExtname(x)
 
 	// 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)
+		sname = strings.Replace(sname, "·", ".", -1)
 	}
 
-	if ctxt.DynlinkingGo() && bind == STB_GLOBAL && ctxt.elfbind == STB_LOCAL && x.Type == sym.STEXT {
+	if ctxt.DynlinkingGo() && bind == STB_GLOBAL && curbind == STB_LOCAL && ldr.SymType(x) == 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
@@ -184,26 +158,79 @@
 		// (*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)
-		ctxt.loader.SetSymLocalElfSym(loader.Sym(x.SymIdx), int32(ctxt.numelfsym))
+		putelfsyment(ctxt.Out, putelfstr("local."+sname), addr, size, STB_LOCAL<<4|typ&0xf, elfshnum, other)
+		ldr.SetSymLocalElfSym(x, int32(ctxt.numelfsym))
 		ctxt.numelfsym++
 		return
-	} else if bind != ctxt.elfbind {
+	} else if bind != curbind {
 		return
 	}
 
-	putelfsyment(ctxt.Out, putelfstr(s), addr, size, bind<<4|typ&0xf, elfshnum, other)
-	ctxt.loader.SetSymElfSym(loader.Sym(x.SymIdx), int32(ctxt.numelfsym))
+	putelfsyment(ctxt.Out, putelfstr(sname), addr, size, bind<<4|typ&0xf, elfshnum, other)
+	ldr.SetSymElfSym(x, int32(ctxt.numelfsym))
 	ctxt.numelfsym++
 }
 
-func putelfsectionsym(ctxt *Link, out *OutBuf, s *sym.Symbol, shndx int) {
+func putelfsectionsym(ctxt *Link, out *OutBuf, s loader.Sym, shndx int) {
 	putelfsyment(out, 0, 0, 0, STB_LOCAL<<4|STT_SECTION, shndx, 0)
-	ctxt.loader.SetSymElfSym(loader.Sym(s.SymIdx), int32(ctxt.numelfsym))
+	ctxt.loader.SetSymElfSym(s, int32(ctxt.numelfsym))
 	ctxt.numelfsym++
 }
 
-func Asmelfsym(ctxt *Link) {
+func genelfsym(ctxt *Link, elfbind int) {
+	ldr := ctxt.loader
+
+	// Text symbols.
+	s := ldr.Lookup("runtime.text", 0)
+	putelfsym(ctxt, s, STT_FUNC, elfbind)
+	for _, s := range ctxt.Textp {
+		putelfsym(ctxt, s, STT_FUNC, elfbind)
+	}
+	s = ldr.Lookup("runtime.etext", 0)
+	if ldr.SymType(s) == sym.STEXT {
+		putelfsym(ctxt, s, STT_FUNC, elfbind)
+	}
+
+	shouldBeInSymbolTable := func(s loader.Sym) bool {
+		if ldr.AttrNotInSymbolTable(s) {
+			return false
+		}
+		// FIXME: avoid having to do name inspections here.
+		sn := ldr.SymName(s)
+		if (sn == "" || sn[0] == '.') && !ldr.IsFileLocal(s) {
+			return false
+		}
+		return true
+	}
+
+	// Data symbols.
+	for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
+		if !ldr.AttrReachable(s) {
+			continue
+		}
+		st := ldr.SymType(s)
+		if st >= sym.SELFRXSECT && st < sym.SXREF {
+			typ := STT_OBJECT
+			if st == sym.STLSBSS {
+				if ctxt.IsInternal() {
+					continue
+				}
+				typ = STT_TLS
+			}
+			if !shouldBeInSymbolTable(s) {
+				continue
+			}
+			putelfsym(ctxt, s, typ, elfbind)
+			continue
+		}
+		if st == sym.SHOSTOBJ || st == sym.SDYNIMPORT || st == sym.SUNDEFEXT {
+			putelfsym(ctxt, s, int(ldr.SymElfType(s)), elfbind)
+		}
+	}
+}
+
+func asmElfSym(ctxt *Link) {
+
 	// the first symbol entry is reserved
 	putelfsyment(ctxt.Out, 0, 0, 0, STB_LOCAL<<4|STT_NOTYPE, 0, 0)
 
@@ -216,45 +243,86 @@
 	putelfsyment(ctxt.Out, putelfstr("go.go"), 0, 0, STB_LOCAL<<4|STT_FILE, SHN_ABS, 0)
 	ctxt.numelfsym++
 
-	ctxt.elfbind = STB_LOCAL
-	genasmsym(ctxt, putelfsym)
-
-	ctxt.elfbind = STB_GLOBAL
-	elfglobalsymndx = ctxt.numelfsym
-	genasmsym(ctxt, putelfsym)
-}
-
-func putplan9sym(ctxt *Link, x *sym.Symbol, s string, typ SymbolType, addr int64) {
-	t := int(typ)
-	switch typ {
-	case TextSym, DataSym, BSSSym:
-		if x.IsFileLocal() {
-			t += 'a' - 'A'
+	bindings := []int{STB_LOCAL, STB_GLOBAL}
+	for _, elfbind := range bindings {
+		if elfbind == STB_GLOBAL {
+			elfglobalsymndx = ctxt.numelfsym
 		}
-		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
+		genelfsym(ctxt, elfbind)
 	}
 }
 
-func Asmplan9sym(ctxt *Link) {
-	genasmsym(ctxt, putplan9sym)
+func putplan9sym(ctxt *Link, ldr *loader.Loader, s loader.Sym, char SymbolType) {
+	t := int(char)
+	if ldr.IsFileLocal(s) {
+		t += 'a' - 'A'
+	}
+	l := 4
+	addr := ldr.SymValue(s)
+	if ctxt.IsAMD64() && !flag8 {
+		ctxt.Out.Write32b(uint32(addr >> 32))
+		l = 8
+	}
+
+	ctxt.Out.Write32b(uint32(addr))
+	ctxt.Out.Write8(uint8(t + 0x80)) /* 0x80 is variable length */
+
+	name := ldr.SymName(s)
+	ctxt.Out.WriteString(name)
+	ctxt.Out.Write8(0)
+
+	symSize += int32(l) + 1 + int32(len(name)) + 1
+}
+
+func asmbPlan9Sym(ctxt *Link) {
+	ldr := ctxt.loader
+
+	// Add special runtime.text and runtime.etext symbols.
+	s := ldr.Lookup("runtime.text", 0)
+	if ldr.SymType(s) == sym.STEXT {
+		putplan9sym(ctxt, ldr, s, TextSym)
+	}
+	s = ldr.Lookup("runtime.etext", 0)
+	if ldr.SymType(s) == sym.STEXT {
+		putplan9sym(ctxt, ldr, s, TextSym)
+	}
+
+	// Add text symbols.
+	for _, s := range ctxt.Textp {
+		putplan9sym(ctxt, ldr, s, TextSym)
+	}
+
+	shouldBeInSymbolTable := func(s loader.Sym) bool {
+		if ldr.AttrNotInSymbolTable(s) {
+			return false
+		}
+		name := ldr.RawSymName(s) // TODO: try not to read the name
+		if name == "" || name[0] == '.' {
+			return false
+		}
+		return true
+	}
+
+	// Add data symbols and external references.
+	for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
+		if !ldr.AttrReachable(s) {
+			continue
+		}
+		t := ldr.SymType(s)
+		if t >= sym.SELFRXSECT && t < sym.SXREF { // data sections handled in dodata
+			if t == sym.STLSBSS {
+				continue
+			}
+			if !shouldBeInSymbolTable(s) {
+				continue
+			}
+			char := DataSym
+			if t == sym.SBSS || t == sym.SNOPTRBSS {
+				char = BSSSym
+			}
+			putplan9sym(ctxt, ldr, s, char)
+		}
+	}
 }
 
 type byPkg []*sym.Library
@@ -342,38 +410,38 @@
 
 	// Define these so that they'll get put into the symbol table.
 	// data.c:/^address will provide the actual values.
-	ctxt.xdefine2("runtime.text", sym.STEXT, 0)
-	ctxt.xdefine2("runtime.etext", sym.STEXT, 0)
-	ctxt.xdefine2("runtime.itablink", sym.SRODATA, 0)
-	ctxt.xdefine2("runtime.eitablink", sym.SRODATA, 0)
-	ctxt.xdefine2("runtime.rodata", sym.SRODATA, 0)
-	ctxt.xdefine2("runtime.erodata", sym.SRODATA, 0)
-	ctxt.xdefine2("runtime.types", sym.SRODATA, 0)
-	ctxt.xdefine2("runtime.etypes", sym.SRODATA, 0)
-	ctxt.xdefine2("runtime.noptrdata", sym.SNOPTRDATA, 0)
-	ctxt.xdefine2("runtime.enoptrdata", sym.SNOPTRDATA, 0)
-	ctxt.xdefine2("runtime.data", sym.SDATA, 0)
-	ctxt.xdefine2("runtime.edata", sym.SDATA, 0)
-	ctxt.xdefine2("runtime.bss", sym.SBSS, 0)
-	ctxt.xdefine2("runtime.ebss", sym.SBSS, 0)
-	ctxt.xdefine2("runtime.noptrbss", sym.SNOPTRBSS, 0)
-	ctxt.xdefine2("runtime.enoptrbss", sym.SNOPTRBSS, 0)
-	ctxt.xdefine2("runtime.end", sym.SBSS, 0)
-	ctxt.xdefine2("runtime.epclntab", sym.SRODATA, 0)
-	ctxt.xdefine2("runtime.esymtab", sym.SRODATA, 0)
+	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 := ldr.CreateSymForUpdate("runtime.gcdata", 0)
 	s.SetType(sym.SRODATA)
 	s.SetSize(0)
 	s.SetReachable(true)
-	ctxt.xdefine2("runtime.egcdata", sym.SRODATA, 0)
+	ctxt.xdefine("runtime.egcdata", sym.SRODATA, 0)
 
 	s = ldr.CreateSymForUpdate("runtime.gcbss", 0)
 	s.SetType(sym.SRODATA)
 	s.SetSize(0)
 	s.SetReachable(true)
-	ctxt.xdefine2("runtime.egcbss", sym.SRODATA, 0)
+	ctxt.xdefine("runtime.egcbss", sym.SRODATA, 0)
 
 	// pseudo-symbols to mark locations of type, string, and go string data.
 	var symtype, symtyperel loader.Sym
@@ -523,13 +591,13 @@
 			s := ldr.CreateSymForUpdate("go.link.pkghashbytes."+l.Pkg, 0)
 			s.SetReachable(true)
 			s.SetType(sym.SRODATA)
-			s.SetSize(int64(len(l.Hash)))
-			s.SetData([]byte(l.Hash))
+			s.SetSize(int64(len(l.Fingerprint)))
+			s.SetData(l.Fingerprint[:])
 			str := ldr.CreateSymForUpdate("go.link.pkghash."+l.Pkg, 0)
 			str.SetReachable(true)
 			str.SetType(sym.SRODATA)
 			str.AddAddr(ctxt.Arch, s.Sym())
-			str.AddUint(ctxt.Arch, uint64(len(l.Hash)))
+			str.AddUint(ctxt.Arch, uint64(len(l.Fingerprint)))
 		}
 	}
 
@@ -539,7 +607,7 @@
 	// 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 := ldr.MakeSymbolUpdater(ctxt.Moduledata2)
+	moduledata := ldr.MakeSymbolUpdater(ctxt.Moduledata)
 	pclntab := ldr.Lookup("runtime.pclntab", 0)
 	// The pclntab slice
 	moduledata.AddAddr(ctxt.Arch, pclntab)
@@ -630,7 +698,7 @@
 			// pkghashes[i].name
 			addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go.link.pkgname.%d", i), l.Pkg)
 			// pkghashes[i].linktimehash
-			addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go.link.pkglinkhash.%d", i), l.Hash)
+			addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go.link.pkglinkhash.%d", i), string(l.Fingerprint[:]))
 			// pkghashes[i].runtimehash
 			hash := ldr.Lookup("go.link.pkghash."+l.Pkg, 0)
 			pkghashes.AddAddr(ctxt.Arch, hash)
diff --git a/src/cmd/link/internal/ld/util.go b/src/cmd/link/internal/ld/util.go
index 2186503..9228ed1 100644
--- a/src/cmd/link/internal/ld/util.go
+++ b/src/cmd/link/internal/ld/util.go
@@ -6,7 +6,6 @@
 
 import (
 	"cmd/link/internal/loader"
-	"cmd/link/internal/sym"
 	"encoding/binary"
 	"fmt"
 	"os"
@@ -57,10 +56,10 @@
 //
 // 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
-	}
+//
+// TODO: remove. Use ctxt.Errof instead.
+// All remaining calls use nil as first arg.
+func Errorf(dummy *int, format string, args ...interface{}) {
 	format += "\n"
 	fmt.Fprintf(os.Stderr, format, args...)
 	afterErrorAction()
@@ -113,10 +112,3 @@
 	}
 	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/link/internal/ld/xcoff.go b/src/cmd/link/internal/ld/xcoff.go
index 281747b..563fe49 100644
--- a/src/cmd/link/internal/ld/xcoff.go
+++ b/src/cmd/link/internal/ld/xcoff.go
@@ -10,6 +10,7 @@
 	"cmd/link/internal/loader"
 	"cmd/link/internal/sym"
 	"encoding/binary"
+	"fmt"
 	"io/ioutil"
 	"math/bits"
 	"path/filepath"
@@ -359,8 +360,7 @@
 
 // xcoffLoaderReloc holds information about a relocation made by the loader.
 type xcoffLoaderReloc struct {
-	sym    *sym.Symbol
-	sym2   loader.Sym
+	sym    loader.Sym
 	roff   int32
 	rtype  uint16
 	symndx int32
@@ -568,7 +568,7 @@
 
 // xcoffUpdateOuterSize stores the size of outer symbols in order to have it
 // in the symbol table.
-func xcoffUpdateOuterSize2(ctxt *Link, size int64, stype sym.SymKind) {
+func xcoffUpdateOuterSize(ctxt *Link, size int64, stype sym.SymKind) {
 	if size == 0 {
 		return
 	}
@@ -616,13 +616,13 @@
 }
 
 // xcoffAlign returns the log base 2 of the symbol's alignment.
-func xcoffAlign(x *sym.Symbol, t SymbolType) uint8 {
-	align := x.Align
+func xcoffAlign(ldr *loader.Loader, x loader.Sym, t SymbolType) uint8 {
+	align := ldr.SymAlign(x)
 	if align == 0 {
 		if t == TextSym {
 			align = int32(Funcalign)
 		} else {
-			align = symalign(x)
+			align = symalign(ldr, x)
 		}
 	}
 	return logBase2(int(align))
@@ -642,6 +642,7 @@
 // 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) {
+	ldr := ctxt.loader
 	/* C_FILE */
 	s := &XcoffSymEnt64{
 		Noffset: uint32(f.stringTable.add(".file")),
@@ -670,8 +671,7 @@
 			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)
+				dwsize = uint64(ldr.SymSize(loader.Sym(sect.Sym)))
 
 			}
 		} else {
@@ -693,8 +693,7 @@
 			// 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)
+			ldr.SetSymDynid(loader.Sym(sect.Sym), int32(f.symbolCount))
 
 			if sect.Name == ".debug_frame" && ctxt.LinkMode != LinkExternal {
 				// CIE size must be added to the first package.
@@ -774,28 +773,30 @@
 // 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 {
+func (f *xcoffFile) writeSymbolFunc(ctxt *Link, x loader.Sym) []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.") {
+	ldr := ctxt.loader
+	name := ldr.SymName(x)
+	if strings.Contains(name, "-tramp") || strings.HasPrefix(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 symPkg(ctxt, x) == "" { // Undefined global symbol
+	} else if ldr.SymPkg(x) == "" { // 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 != symPkg(ctxt, x) {
+		if currSymSrcFile.name != ldr.SymPkg(x) {
 			if ctxt.LinkMode == LinkInternal {
 				// update previous file values
 				xfile.updatePreviousFile(ctxt, false)
-				currSymSrcFile.name = symPkg(ctxt, x)
-				f.writeSymbolNewFile(ctxt, symPkg(ctxt, x), uint64(x.Value), xfile.getXCOFFscnum(x.Sect))
+				currSymSrcFile.name = ldr.SymPkg(x)
+				f.writeSymbolNewFile(ctxt, ldr.SymPkg(x), uint64(ldr.SymValue(x)), xfile.getXCOFFscnum(ldr.SymSect(x)))
 			} else {
 				// With external linking, ld will crash if there is several
 				// .FILE and DWARF debugging enable, somewhere during
@@ -805,8 +806,8 @@
 				// TODO(aix); remove once ld has been fixed or the triggering
 				// relocation has been found and fixed.
 				if currSymSrcFile.name == "" {
-					currSymSrcFile.name = symPkg(ctxt, x)
-					f.writeSymbolNewFile(ctxt, "go_functions", uint64(x.Value), xfile.getXCOFFscnum(x.Sect))
+					currSymSrcFile.name = ldr.SymPkg(x)
+					f.writeSymbolNewFile(ctxt, "go_functions", uint64(ldr.SymValue(x)), xfile.getXCOFFscnum(ldr.SymSect(x)))
 				}
 			}
 
@@ -815,26 +816,26 @@
 
 	s := &XcoffSymEnt64{
 		Nsclass: C_EXT,
-		Noffset: uint32(xfile.stringTable.add(x.Extname())),
-		Nvalue:  uint64(x.Value),
-		Nscnum:  f.getXCOFFscnum(x.Sect),
+		Noffset: uint32(xfile.stringTable.add(ldr.SymExtname(x))),
+		Nvalue:  uint64(ldr.SymValue(x)),
+		Nscnum:  f.getXCOFFscnum(ldr.SymSect(x)),
 		Ntype:   SYM_TYPE_FUNC,
 		Nnumaux: 2,
 	}
 
-	if x.Version != 0 || x.Attr.VisibilityHidden() || x.Attr.Local() {
+	if ldr.SymVersion(x) != 0 || ldr.AttrVisibilityHidden(x) || ldr.AttrLocal(x) {
 		s.Nsclass = C_HIDEXT
 	}
 
-	x.Dynid = int32(xfile.symbolCount)
+	ldr.SetSymDynid(x, int32(xfile.symbolCount))
 	syms = append(syms, s)
 
 	// Update current csect size
-	currSymSrcFile.csectSize += x.Size
+	currSymSrcFile.csectSize += ldr.SymSize(x)
 
 	// create auxiliary entries
 	a2 := &XcoffAuxFcn64{
-		Xfsize:   uint32(x.Size),
+		Xfsize:   uint32(ldr.SymSize(x)),
 		Xlnnoptr: 0,                     // TODO
 		Xendndx:  xfile.symbolCount + 3, // this symbol + 2 aux entries
 		Xauxtype: _AUX_FCN,
@@ -848,44 +849,49 @@
 		Xsmtyp:    XTY_LD, // label definition (based on C)
 		Xauxtype:  _AUX_CSECT,
 	}
-	a4.Xsmtyp |= uint8(xcoffAlign(x, TextSym) << 3)
+	a4.Xsmtyp |= uint8(xcoffAlign(ldr, 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) {
-
+func putaixsym(ctxt *Link, x loader.Sym, t SymbolType) {
 	// All XCOFF symbols generated by this GO symbols
 	// Can be a symbol entry or a auxiliary entry
 	syms := []xcoffSym{}
 
+	ldr := ctxt.loader
+	name := ldr.SymName(x)
+	if t == UndefinedSym {
+		name = ldr.SymExtname(x)
+	}
+
 	switch t {
 	default:
 		return
 
 	case TextSym:
-		if symPkg(ctxt, x) != "" || strings.Contains(x.Name, "-tramp") || strings.HasPrefix(x.Name, "runtime.text.") {
+		if ldr.SymPkg(x) != "" || strings.Contains(name, "-tramp") || strings.HasPrefix(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)
+			if name != "runtime.text" && name != "runtime.etext" && name != "go.buildid" {
+				Exitf("putaixsym: unknown text symbol %s", name)
 			}
 			s := &XcoffSymEnt64{
 				Nsclass: C_HIDEXT,
-				Noffset: uint32(xfile.stringTable.add(str)),
-				Nvalue:  uint64(x.Value),
-				Nscnum:  xfile.getXCOFFscnum(x.Sect),
+				Noffset: uint32(xfile.stringTable.add(name)),
+				Nvalue:  uint64(ldr.SymValue(x)),
+				Nscnum:  xfile.getXCOFFscnum(ldr.SymSect(x)),
 				Ntype:   SYM_TYPE_FUNC,
 				Nnumaux: 1,
 			}
-			x.Dynid = int32(xfile.symbolCount)
+			ldr.SetSymDynid(x, int32(xfile.symbolCount))
 			syms = append(syms, s)
 
-			size := uint64(x.Size)
+			size := uint64(ldr.SymSize(x))
 			a4 := &XcoffAuxCSect64{
 				Xauxtype:  _AUX_CSECT,
 				Xscnlenlo: uint32(size & 0xFFFFFFFF),
@@ -893,21 +899,20 @@
 				Xsmclas:   XMC_PR,
 				Xsmtyp:    XTY_SD,
 			}
-			a4.Xsmtyp |= uint8(xcoffAlign(x, TextSym) << 3)
+			a4.Xsmtyp |= uint8(xcoffAlign(ldr, 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),
+			Noffset: uint32(xfile.stringTable.add(name)),
+			Nvalue:  uint64(ldr.SymValue(x)),
+			Nscnum:  xfile.getXCOFFscnum(ldr.SymSect(x)),
 			Nnumaux: 1,
 		}
 
-		if x.Version != 0 || x.Attr.VisibilityHidden() || x.Attr.Local() {
+		if ldr.SymVersion(x) != 0 || ldr.AttrVisibilityHidden(x) || ldr.AttrLocal(x) {
 			// There is more symbols in the case of a global data
 			// which are related to the assembly generated
 			// to access such symbols.
@@ -917,7 +922,7 @@
 			s.Nsclass = C_HIDEXT
 		}
 
-		x.Dynid = int32(xfile.symbolCount)
+		ldr.SetSymDynid(x, int32(xfile.symbolCount))
 		syms = append(syms, s)
 
 		// Create auxiliary entry
@@ -926,15 +931,15 @@
 		// 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)
+		size := uint64(ldr.SymSize(x))
 		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") {
+		if ty := ldr.SymType(x); ty >= sym.STYPE && ty <= sym.SPCLNTAB {
+			if ctxt.IsExternal() && strings.HasPrefix(ldr.SymSect(x).Name, ".data.rel.ro") {
 				// During external linking, read-only datas with relocation
 				// must be in .data.
 				a4.Xsmclas = XMC_RW
@@ -942,9 +947,9 @@
 				// Read only data
 				a4.Xsmclas = XMC_RO
 			}
-		} else if x.Type == sym.SDATA && strings.HasPrefix(x.Name, "TOC.") && ctxt.LinkMode == LinkExternal {
+		} else if /*ty == sym.SDATA &&*/ strings.HasPrefix(ldr.SymName(x), "TOC.") && ctxt.IsExternal() {
 			a4.Xsmclas = XMC_TC
-		} else if x.Name == "TOC" {
+		} else if ldr.SymName(x) == "TOC" {
 			a4.Xsmclas = XMC_TC0
 		} else {
 			a4.Xsmclas = XMC_RW
@@ -955,20 +960,20 @@
 			a4.Xsmtyp |= XTY_CM
 		}
 
-		a4.Xsmtyp |= uint8(xcoffAlign(x, t) << 3)
+		a4.Xsmtyp |= uint8(xcoffAlign(ldr, x, t) << 3)
 
 		syms = append(syms, a4)
 
 	case UndefinedSym:
-		if x.Type != sym.SDYNIMPORT && x.Type != sym.SHOSTOBJ && x.Type != sym.SUNDEFEXT {
+		if ty := ldr.SymType(x); ty != sym.SDYNIMPORT && ty != sym.SHOSTOBJ && ty != sym.SUNDEFEXT {
 			return
 		}
 		s := &XcoffSymEnt64{
 			Nsclass: C_EXT,
-			Noffset: uint32(xfile.stringTable.add(str)),
+			Noffset: uint32(xfile.stringTable.add(name)),
 			Nnumaux: 1,
 		}
-		x.Dynid = int32(xfile.symbolCount)
+		ldr.SetSymDynid(x, int32(xfile.symbolCount))
 		syms = append(syms, s)
 
 		a4 := &XcoffAuxCSect64{
@@ -977,7 +982,7 @@
 			Xsmtyp:   XTY_ER | XTY_IMP,
 		}
 
-		if x.Name == "__n_pthreads" {
+		if ldr.SymName(x) == "__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.
@@ -989,16 +994,16 @@
 	case TLSSym:
 		s := &XcoffSymEnt64{
 			Nsclass: C_EXT,
-			Noffset: uint32(xfile.stringTable.add(str)),
-			Nscnum:  xfile.getXCOFFscnum(x.Sect),
-			Nvalue:  uint64(x.Value),
+			Noffset: uint32(xfile.stringTable.add(name)),
+			Nscnum:  xfile.getXCOFFscnum(ldr.SymSect(x)),
+			Nvalue:  uint64(ldr.SymValue(x)),
 			Nnumaux: 1,
 		}
 
-		x.Dynid = int32(xfile.symbolCount)
+		ldr.SetSymDynid(x, int32(xfile.symbolCount))
 		syms = append(syms, s)
 
-		size := uint64(x.Size)
+		size := uint64(ldr.SymSize(x))
 		a4 := &XcoffAuxCSect64{
 			Xauxtype:  _AUX_CSECT,
 			Xsmclas:   XMC_UL,
@@ -1019,18 +1024,114 @@
 // 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) {
+	ldr := ctxt.loader
 	// 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 {
+		sym := ldr.Lookup(name, 0)
+		if sym == 0 {
 			Errorf(nil, "unknown outer symbol with name %s", name)
 		} else {
-			sym.Size = size
+			s := ldr.MakeSymbolUpdater(sym)
+			s.SetSize(size)
 		}
 	}
 
-	genasmsym(ctxt, putaixsym)
+	// 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 := ldr.Lookup("runtime.text", 0)
+	if ldr.SymType(s) == sym.STEXT {
+		// We've already included this symbol in ctxt.Textp on AIX with external linker.
+		// See data.go:/textaddress
+		if !ctxt.IsExternal() {
+			putaixsym(ctxt, s, TextSym)
+		}
+	}
+
+	n := 1
+	// Generate base addresses for all text sections if there are multiple
+	for _, sect := range Segtext.Sections[1:] {
+		if sect.Name != ".text" || ctxt.IsExternal() {
+			// On AIX, runtime.text.X are symbols already in the symtab.
+			break
+		}
+		s = ldr.Lookup(fmt.Sprintf("runtime.text.%d", n), 0)
+		if s == 0 {
+			break
+		}
+		if ldr.SymType(s) == sym.STEXT {
+			putaixsym(ctxt, s, TextSym)
+		}
+		n++
+	}
+
+	s = ldr.Lookup("runtime.etext", 0)
+	if ldr.SymType(s) == sym.STEXT {
+		// We've already included this symbol in ctxt.Textp
+		// on AIX with external linker.
+		// See data.go:/textaddress
+		if !ctxt.IsExternal() {
+			putaixsym(ctxt, s, TextSym)
+		}
+	}
+
+	shouldBeInSymbolTable := func(s loader.Sym, name string) bool {
+		if name == ".go.buildinfo" {
+			// On AIX, .go.buildinfo must be in the symbol table as
+			// it has relocations.
+			return true
+		}
+		if ldr.AttrNotInSymbolTable(s) {
+			return false
+		}
+		if (name == "" || name[0] == '.') && !ldr.IsFileLocal(s) && name != ".TOC." {
+			return false
+		}
+		return true
+	}
+
+	for s, nsym := loader.Sym(1), loader.Sym(ldr.NSym()); s < nsym; s++ {
+		if !shouldBeInSymbolTable(s, ldr.SymName(s)) {
+			continue
+		}
+		st := ldr.SymType(s)
+		switch {
+		case st == sym.STLSBSS:
+			if ctxt.IsExternal() {
+				putaixsym(ctxt, s, TLSSym)
+			}
+
+		case st == sym.SBSS, st == sym.SNOPTRBSS, st == sym.SLIBFUZZER_EXTRA_COUNTER:
+			if ldr.AttrReachable(s) {
+				data := ldr.Data(s)
+				if len(data) > 0 {
+					ldr.Errorf(s, "should not be bss (size=%d type=%v special=%v)", len(data), ldr.SymType(s), ldr.AttrSpecial(s))
+				}
+				putaixsym(ctxt, s, BSSSym)
+			}
+
+		case st >= sym.SELFRXSECT && st < sym.SXREF: // data sections handled in dodata
+			if ldr.AttrReachable(s) {
+				putaixsym(ctxt, s, DataSym)
+			}
+
+		case st == sym.SUNDEFEXT:
+			putaixsym(ctxt, s, UndefinedSym)
+
+		case st == sym.SDYNIMPORT:
+			if ldr.AttrReachable(s) {
+				putaixsym(ctxt, s, UndefinedSym)
+			}
+		}
+	}
+
+	for _, s := range ctxt.Textp {
+		putaixsym(ctxt, s, TextSym)
+	}
+
+	if ctxt.Debugvlog != 0 || *flagN {
+		ctxt.Logf("symsize = %d\n", uint32(symSize))
+	}
 	xfile.updatePreviousFile(ctxt, true)
 }
 
@@ -1109,7 +1210,7 @@
 
 // Xcoffadddynrel adds a dynamic relocation in a XCOFF file.
 // This relocation will be made by the loader.
-func Xcoffadddynrel2(target *Target, ldr *loader.Loader, syms *ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
+func Xcoffadddynrel(target *Target, ldr *loader.Loader, syms *ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
 	if target.IsExternal() {
 		return true
 	}
@@ -1119,10 +1220,10 @@
 	}
 
 	xldr := &xcoffLoaderReloc{
-		sym2: s,
+		sym:  s,
 		roff: r.Off(),
 	}
-	targ := r.Sym()
+	targ := ldr.ResolveABIAlias(r.Sym())
 	var targType sym.SymKind
 	if targ != 0 {
 		targType = ldr.SymType(targ)
@@ -1264,6 +1365,7 @@
 		Lsymoff:  LDHDRSZ_64,
 	}
 
+	ldr := ctxt.loader
 	/* Symbol table */
 	for _, s := range f.loaderSymbols {
 		lds := &XcoffLdSym64{
@@ -1271,19 +1373,19 @@
 			Lsmtype: s.smtype,
 			Lsmclas: s.smclas,
 		}
-		sym := ctxt.loader.Syms[s.sym]
+		sym := s.sym
 		switch s.smtype {
 		default:
-			Errorf(sym, "unexpected loader symbol type: 0x%x", s.smtype)
+			ldr.Errorf(sym, "unexpected loader symbol type: 0x%x", s.smtype)
 		case XTY_ENT | XTY_SD:
-			lds.Lvalue = uint64(sym.Value)
-			lds.Lscnum = f.getXCOFFscnum(sym.Sect)
+			lds.Lvalue = uint64(ldr.SymValue(sym))
+			lds.Lscnum = f.getXCOFFscnum(ldr.SymSect(sym))
 		case XTY_IMP:
-			lds.Lifile = int32(f.dynLibraries[sym.Dynimplib()] + 1)
+			lds.Lifile = int32(f.dynLibraries[ldr.SymDynimplib(sym)] + 1)
 		}
 		ldstr := &XcoffLdStr64{
-			size: uint16(len(sym.Name) + 1), // + null terminator
-			name: sym.Name,
+			size: uint16(len(ldr.SymName(sym)) + 1), // + null terminator
+			name: ldr.SymName(sym),
 		}
 		stlen += uint32(2 + ldstr.size) // 2 = sizeof ldstr.size
 		symtab = append(symtab, lds)
@@ -1296,11 +1398,11 @@
 	off := hdr.Lrldoff                                // current offset is the same of reloc offset
 
 	/* Reloc */
-	ep := ctxt.Syms.ROLookup(*flagEntrySymbol, 0)
+	ep := ldr.Lookup(*flagEntrySymbol, 0)
 	xldr := &XcoffLdRel64{
-		Lvaddr:  uint64(ep.Value),
+		Lvaddr:  uint64(ldr.SymValue(ep)),
 		Lrtype:  0x3F00,
-		Lrsecnm: f.getXCOFFscnum(ep.Sect),
+		Lrsecnm: f.getXCOFFscnum(ldr.SymSect(ep)),
 		Lsymndx: 0,
 	}
 	off += 16
@@ -1309,17 +1411,17 @@
 	off += uint64(16 * len(f.loaderReloc))
 	for _, r := range f.loaderReloc {
 		symp := r.sym
-		if symp == nil {
-			symp = ctxt.loader.Syms[r.sym2]
+		if symp == 0 {
+			panic("unexpected 0 sym value")
 		}
 		xldr = &XcoffLdRel64{
-			Lvaddr:  uint64(symp.Value + int64(r.roff)),
+			Lvaddr:  uint64(ldr.SymValue(symp) + int64(r.roff)),
 			Lrtype:  r.rtype,
 			Lsymndx: r.symndx,
 		}
 
-		if symp.Sect != nil {
-			xldr.Lrsecnm = f.getXCOFFscnum(symp.Sect)
+		if ldr.SymSect(symp) != nil {
+			xldr.Lrsecnm = f.getXCOFFscnum(ldr.SymSect(symp))
 		}
 
 		reloctab = append(reloctab, xldr)
@@ -1416,6 +1518,7 @@
 	}
 
 	if ctxt.BuildMode == BuildModeExe && ctxt.LinkMode == LinkInternal {
+		ldr := ctxt.loader
 		f.xfhdr.Fopthdr = AOUTHSZ_EXEC64
 		f.xfhdr.Fflags = F_EXEC
 
@@ -1423,12 +1526,12 @@
 		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)
+		entry := ldr.Lookup(*flagEntrySymbol, 0)
+		f.xahdr.Oentry = uint64(ldr.SymValue(entry))
+		f.xahdr.Osnentry = f.getXCOFFscnum(ldr.SymSect(entry))
+		toc := ldr.Lookup("TOC", 0)
+		f.xahdr.Otoc = uint64(ldr.SymValue(toc))
+		f.xahdr.Osntoc = f.getXCOFFscnum(ldr.SymSect(toc))
 
 		f.xahdr.Oalgntext = int16(logBase2(int(Funcalign)))
 		f.xahdr.Oalgndata = 0x5
@@ -1453,7 +1556,11 @@
 }
 
 // Generate XCOFF assembly file
-func Asmbxcoff(ctxt *Link, fileoff int64) {
+func asmbXcoff(ctxt *Link) {
+	ctxt.Out.SeekSet(0)
+	fileoff := int64(Segdwarf.Fileoff + Segdwarf.Filelen)
+	fileoff = int64(Rnd(int64(fileoff), int64(*FlagRound)))
+
 	xfile.sectNameToScnum = make(map[string]int16)
 
 	// Add sections
@@ -1534,19 +1641,6 @@
 	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)
@@ -1554,9 +1648,10 @@
 		ctxt.Out.Write8(0)
 	}
 
+	ldr := ctxt.loader
 	// 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 {
+	relocsect := func(sect *sym.Section, syms []loader.Sym, 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 {
@@ -1564,42 +1659,45 @@
 		}
 		sect.Reloff = uint64(ctxt.Out.Offset())
 		for i, s := range syms {
-			if !s.Attr.Reachable() {
+			if !ldr.AttrReachable(s) {
 				continue
 			}
-			if uint64(s.Value) >= sect.Vaddr {
+			if uint64(ldr.SymValue(s)) >= sect.Vaddr {
 				syms = syms[i:]
 				break
 			}
 		}
 		eaddr := int64(sect.Vaddr + sect.Length)
 		for _, s := range syms {
-			if !s.Attr.Reachable() {
+			if !ldr.AttrReachable(s) {
 				continue
 			}
-			if s.Value >= int64(eaddr) {
+			if ldr.SymValue(s) >= int64(eaddr) {
 				break
 			}
 
-			// Relocation must be ordered by address, so s.R is ordered by Off.
-			sort.Sort(byOffset(s.R))
+			// Relocation must be ordered by address, so create a list of sorted indices.
+			relocs := ldr.ExtRelocs(s)
+			sorted := make([]int, relocs.Count())
+			for i := 0; i < relocs.Count(); i++ {
+				sorted[i] = i
+			}
+			sort.Slice(sorted, func(i, j int) bool {
+				return relocs.At(sorted[i]).Off() < relocs.At(sorted[j]).Off()
+			})
 
-			for ri := range s.R {
+			for _, ri := range sorted {
+				r := relocs.At(ri)
 
-				r := &s.R[ri]
-
-				if r.Done {
+				if r.Xsym == 0 {
+					ldr.Errorf(s, "missing xsym in relocation")
 					continue
 				}
-				if r.Xsym == nil {
-					Errorf(s, "missing xsym in relocation")
-					continue
+				if ldr.SymDynid(r.Xsym) < 0 {
+					ldr.Errorf(s, "reloc %s to non-coff symbol %s (outer=%s) %d %d", r.Type(), ldr.SymName(r.Sym()), ldr.SymName(r.Xsym), ldr.SymType(r.Sym()), ldr.SymDynid(r.Xsym))
 				}
-				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)
+				if !thearch.Xcoffreloc1(ctxt.Arch, ctxt.Out, ldr, s, r, int64(uint64(ldr.SymValue(s)+int64(r.Off()))-base)) {
+					ldr.Errorf(s, "unsupported obj reloc %d(%s)/%d to %s", r.Type(), r.Type(), r.Siz(), ldr.SymName(r.Sym()))
 				}
 			}
 		}
@@ -1632,8 +1730,8 @@
 	for i := 0; i < len(Segdwarf.Sections); i++ {
 		sect := Segdwarf.Sections[i]
 		si := dwarfp[i]
-		if si.secSym() != sect.Sym ||
-			si.secSym().Sect != sect {
+		if si.secSym() != loader.Sym(sect.Sym) ||
+			ldr.SymSect(si.secSym()) != sect {
 			panic("inconsistency between dwarfp and Segdwarf")
 		}
 		for _, xcoffSect := range f.sections {
@@ -1655,17 +1753,16 @@
 	fname = filepath.Join(*flagTmpdir, "export_file.exp")
 	var buf bytes.Buffer
 
-	for _, s := range ctxt.loader.Syms {
-		if s == nil {
+	ldr := ctxt.loader
+	for s, nsym := loader.Sym(1), loader.Sym(ldr.NSym()); s < nsym; s++ {
+		if !ldr.AttrCgoExport(s) {
 			continue
 		}
-		if !s.Attr.CgoExport() {
+		extname := ldr.SymExtname(s)
+		if !strings.HasPrefix(extname, "._cgoexp_") {
 			continue
 		}
-		if !strings.HasPrefix(s.Extname(), "._cgoexp_") {
-			continue
-		}
-		if s.Version != 0 {
+		if ldr.SymVersion(s) != 0 {
 			continue // Only export version 0 symbols. See the comment in doxcoff.
 		}
 
@@ -1673,7 +1770,7 @@
 		// exported by cgo.
 		// The corresponding Go symbol is:
 		// _cgoexp_hashcode_symname.
-		name := strings.SplitN(s.Extname(), "_", 4)[3]
+		name := strings.SplitN(extname, "_", 4)[3]
 
 		buf.Write([]byte(name + "\n"))
 	}
@@ -1684,5 +1781,4 @@
 	}
 
 	return fname
-
 }
diff --git a/src/cmd/link/internal/ld/xcoff2.go b/src/cmd/link/internal/ld/xcoff2.go
deleted file mode 100644
index 27edbcb..0000000
--- a/src/cmd/link/internal/ld/xcoff2.go
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2020 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/link/internal/loader"
-	"cmd/link/internal/sym"
-)
-
-// Temporary dumping around for sym.Symbol version of helper
-// functions in xcoff.go, still being used for some archs/oses.
-// FIXME: get rid of this file when dodata() is completely
-// converted.
-
-// 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
-
-	}
-}
-
-// Xcoffadddynrel adds a dynamic relocation in a XCOFF file.
-// This relocation will be made by the loader.
-func Xcoffadddynrel(target *Target, ldr *loader.Loader, s *sym.Symbol, r *sym.Reloc) bool {
-	if target.IsExternal() {
-		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
-	}
-
-	xldr := &xcoffLoaderReloc{
-		sym:  s,
-		roff: r.Off,
-	}
-
-	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 ldr.Syms[dynsym.sym].Name == r.Sym.Name {
-					xldr.symndx = int32(i + 3) // +3 because of 3 section symbols
-					break
-				}
-			}
-		} else if s.Type == sym.SDATA || s.Type == sym.SNOPTRDATA || s.Type == sym.SBUILDINFO || s.Type == sym.SXCOFFTOC {
-			switch r.Sym.Sect.Seg {
-			default:
-				Errorf(s, "unknown segment for .loader relocation with symbol %s", r.Sym.Name)
-			case &Segtext:
-			case &Segrodata:
-				xldr.symndx = 0 // .text
-			case &Segdata:
-				if r.Sym.Type == sym.SBSS || r.Sym.Type == sym.SNOPTRBSS {
-					xldr.symndx = 2 // .bss
-				} else {
-					xldr.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
-		}
-
-		xldr.rtype = 0x3F<<8 + XCOFF_R_POS
-	}
-
-	xfile.loaderReloc = append(xfile.loaderReloc, xldr)
-	return true
-}
diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go
index ab38bc3..9b4214b 100644
--- a/src/cmd/link/internal/loader/loader.go
+++ b/src/cmd/link/internal/loader/loader.go
@@ -33,7 +33,7 @@
 type Relocs struct {
 	rs []goobj2.Reloc
 
-	li int      // local index of symbol whose relocs we're examining
+	li uint32   // local index of symbol whose relocs we're examining
 	r  *oReader // object reader for containing package
 	l  *Loader  // loader
 }
@@ -125,12 +125,12 @@
 
 // objSym represents a symbol in an object file. It is a tuple of
 // the object and the symbol's local index.
-// For external symbols, r is l.extReader, s is its index into the
-// payload array.
-// {nil, 0} represents the nil symbol.
+// For external symbols, objidx is the index of l.extReader (extObj),
+// s is its index into the payload array.
+// {0, 0} represents the nil symbol.
 type objSym struct {
-	r *oReader
-	s int // local index
+	objidx uint32 // index of the object (in l.objs array)
+	s      uint32 // local index
 }
 
 type nameVer struct {
@@ -202,13 +202,6 @@
 //   extending the external symbol index space range. The host object
 //   loader stores symbol payloads in loader.payloads using SymbolBuilder.
 //
-// - For now, in loader.LoadFull we convert all symbols (Go + external)
-//   to sym.Symbols.
-//
-// - At some point (when the wayfront is pushed through all of the
-//   linker), all external symbols will be payload-based, and we can
-//   get rid of the loader.Syms array.
-//
 // - Each symbol gets a unique global index. For duplicated and
 //   overwriting/overwritten symbols, the second (or later) appearance
 //   of the symbol gets the same global index as the first appearance.
@@ -241,9 +234,6 @@
 
 	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.
-	symBatch []sym.Symbol  // batch of symbols.
-
 	anonVersion int // most recently assigned ext static sym pseudo-version
 
 	// Bitmaps and other side structures used to store data used to store
@@ -293,9 +283,6 @@
 	// the symbol that triggered the marking of symbol K as live.
 	Reachparent []Sym
 
-	relocBatch    []sym.Reloc    // for bulk allocation of relocations
-	relocExtBatch []sym.RelocExt // for bulk allocation of relocations
-
 	flags uint32
 
 	strictDupMsgs int // number of strict-dup warning/errors, when FlagStrictDups is enabled
@@ -303,8 +290,6 @@
 	elfsetstring elfsetstringFunc
 
 	errorReporter *ErrorReporter
-
-	SymLookup func(name string, ver int) *sym.Symbol
 }
 
 const (
@@ -313,7 +298,14 @@
 	nonPkgRef
 )
 
-type elfsetstringFunc func(s *sym.Symbol, str string, off int)
+// objidx
+const (
+	nilObj = iota
+	extObj
+	goObjStart
+)
+
+type elfsetstringFunc func(str string, off int)
 
 // extSymPayload holds the payload (data + relocations) for linker-synthesized
 // external symbols (note that symbol value is stored in a separate slice).
@@ -323,7 +315,6 @@
 	ver      int
 	kind     sym.SymKind
 	objidx   uint32 // index of original object if sym made by cloneToExternal
-	gotype   Sym    // Gotype (0 if not present)
 	relocs   []goobj2.Reloc
 	reltypes []objabi.RelocType // relocation types
 	data     []byte
@@ -337,11 +328,12 @@
 
 func NewLoader(flags uint32, elfsetstring elfsetstringFunc, reporter *ErrorReporter) *Loader {
 	nbuiltin := goobj2.NBuiltin()
+	extReader := &oReader{objidx: extObj}
 	ldr := &Loader{
 		start:                make(map[*oReader]Sym),
-		objs:                 []objIdx{{}}, // reserve index 0 for nil symbol
-		objSyms:              []objSym{{}}, // reserve index 0 for nil symbol
-		extReader:            &oReader{},
+		objs:                 []objIdx{{}, {extReader, 0}}, // reserve index 0 for nil symbol, 1 for external symbols
+		objSyms:              make([]objSym, 1, 100000),    // reserve index 0 for nil symbol
+		extReader:            extReader,
 		symsByName:           [2]map[string]Sym{make(map[string]Sym, 100000), make(map[string]Sym, 50000)}, // preallocate ~2MB for ABI0 and ~1MB for ABI1 symbols
 		objByPkg:             make(map[string]*oReader),
 		outer:                make(map[Sym]Sym),
@@ -392,13 +384,13 @@
 
 // Add a symbol from an object file, return the global index and whether it is added.
 // If the symbol already exist, it returns the index of that symbol.
-func (l *Loader) AddSym(name string, ver int, r *oReader, li int, kind int, dupok bool, typ sym.SymKind) (Sym, bool) {
+func (l *Loader) AddSym(name string, ver int, r *oReader, li uint32, kind int, dupok bool, typ sym.SymKind) (Sym, bool) {
 	if l.extStart != 0 {
 		panic("AddSym called after external symbol is created")
 	}
 	i := Sym(len(l.objSyms))
 	addToGlobal := func() {
-		l.objSyms = append(l.objSyms, objSym{r, li})
+		l.objSyms = append(l.objSyms, objSym{r.objidx, li})
 	}
 	if name == "" {
 		addToGlobal()
@@ -448,7 +440,7 @@
 		if !(oldtyp.IsData() && oldr.DataSize(oldli) == 0) {
 			log.Fatalf("duplicated definition of symbol " + name)
 		}
-		l.objSyms[oldi] = objSym{r, li}
+		l.objSyms[oldi] = objSym{r.objidx, li}
 	} else {
 		// old symbol overwrites new symbol.
 		if !typ.IsData() { // only allow overwriting data symbol
@@ -465,9 +457,10 @@
 	if l.extStart == 0 {
 		l.extStart = i
 	}
-	l.growSyms(int(i))
+	l.growValues(int(i) + 1)
+	l.growAttrBitmaps(int(i) + 1)
 	pi := l.newPayload(name, ver)
-	l.objSyms = append(l.objSyms, objSym{l.extReader, int(pi)})
+	l.objSyms = append(l.objSyms, objSym{l.extReader.objidx, uint32(pi)})
 	l.extReader.syms = append(l.extReader.syms, i)
 	return i
 }
@@ -556,25 +549,14 @@
 	ms.data = ms.data[:siz]
 }
 
-// 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)...)
-	l.growValues(int(i) + 1)
-	l.growAttrBitmaps(int(i) + 1)
-}
-
 // Convert a local index to a global index.
-func (l *Loader) toGlobal(r *oReader, i int) Sym {
+func (l *Loader) toGlobal(r *oReader, i uint32) Sym {
 	return r.syms[i]
 }
 
 // Convert a global index to a local index.
-func (l *Loader) toLocal(i Sym) (*oReader, int) {
-	return l.objSyms[i].r, int(l.objSyms[i].s)
+func (l *Loader) toLocal(i Sym) (*oReader, uint32) {
+	return l.objs[l.objSyms[i].objidx].r, l.objSyms[i].s
 }
 
 // Resolve a local symbol reference. Return global index.
@@ -607,7 +589,7 @@
 			log.Fatalf("reference of nonexisted package %s, from %v", pkg, r.unit.Lib)
 		}
 	}
-	return l.toGlobal(rr, int(s.SymIdx))
+	return l.toGlobal(rr, s.SymIdx)
 }
 
 // Look up a symbol by name, return global index, or 0 if not found.
@@ -621,7 +603,7 @@
 }
 
 // Check that duplicate symbols have same contents.
-func (l *Loader) checkdup(name string, r *oReader, li int, dup Sym) {
+func (l *Loader) checkdup(name string, r *oReader, li uint32, dup Sym) {
 	p := r.Data(li)
 	rdup, ldup := l.toLocal(dup)
 	pdup := rdup.Data(ldup)
@@ -681,7 +663,11 @@
 		return pp.name
 	}
 	r, li := l.toLocal(i)
-	return strings.Replace(r.Sym(li).Name(r.Reader), "\"\".", r.pkgprefix, -1)
+	name := r.Sym(li).Name(r.Reader)
+	if !r.NeedNameExpansion() {
+		return name
+	}
+	return strings.Replace(name, "\"\".", r.pkgprefix, -1)
 }
 
 // Returns the version of the i-th symbol.
@@ -694,6 +680,8 @@
 	return int(abiToVer(r.Sym(li).ABI(), r.version))
 }
 
+func (l *Loader) IsFileLocal(i Sym) bool { return l.SymVersion(i) >= sym.SymVerStatic }
+
 // Returns the type of the i-th symbol.
 func (l *Loader) SymType(i Sym) sym.SymKind {
 	if l.IsExternal(i) {
@@ -861,7 +849,7 @@
 		// might make more sense to copy the flag value out of the
 		// object into a larger bitmap during preload.
 		r, _ := l.toLocal(i)
-		return (r.Flags() & goobj2.ObjFlagShared) != 0
+		return r.Shared()
 	}
 	return l.attrShared.Has(l.extIndex(i))
 }
@@ -1190,7 +1178,7 @@
 	return l.sects[l.symSects[i]]
 }
 
-// SetSymValue sets the section of the i-th symbol. i is global index.
+// SetSymSect sets the section of the i-th symbol. i is global index.
 func (l *Loader) SetSymSect(i Sym, sect *sym.Section) {
 	if int(i) >= len(l.symSects) {
 		l.symSects = append(l.symSects, make([]uint16, l.NSym()-len(l.symSects))...)
@@ -1420,12 +1408,17 @@
 // results in to a map (might want to try this at some point and see
 // if it helps speed things up).
 func (l *Loader) SymGoType(i Sym) Sym {
+	var r *oReader
+	var auxs []goobj2.Aux
 	if l.IsExternal(i) {
 		pp := l.getPayload(i)
-		return pp.gotype
+		r = l.objs[pp.objidx].r
+		auxs = pp.auxs
+	} else {
+		var li uint32
+		r, li = l.toLocal(i)
+		auxs = r.Auxs(li)
 	}
-	r, li := l.toLocal(i)
-	auxs := r.Auxs(li)
 	for j := range auxs {
 		a := &auxs[j]
 		switch a.Type() {
@@ -1546,7 +1539,7 @@
 		switch a.Type() {
 		case goobj2.AuxDwarfInfo:
 			auxDwarfInfo = l.resolve(r, a.Sym())
-			if l.SymType(auxDwarfInfo) != sym.SDWARFINFO {
+			if l.SymType(auxDwarfInfo) != sym.SDWARFFCN {
 				panic("aux dwarf info sym with wrong type")
 			}
 		case goobj2.AuxDwarfLoc:
@@ -1608,6 +1601,11 @@
 func (l *Loader) SetOuterSym(i Sym, o Sym) {
 	if o != 0 {
 		l.outer[i] = o
+		// relocsym's foldSubSymbolOffset requires that we only
+		// have a single level of containment-- enforce here.
+		if l.outer[o] != 0 {
+			panic("multiply nested outer sym")
+		}
 	} else {
 		delete(l.outer, i)
 	}
@@ -1703,7 +1701,7 @@
 }
 
 // Relocs returns a Relocs object given a local sym index and reader.
-func (l *Loader) relocs(r *oReader, li int) Relocs {
+func (l *Loader) relocs(r *oReader, li uint32) Relocs {
 	var rs []goobj2.Reloc
 	if l.isExtReader(r) {
 		pp := l.payloads[li]
@@ -1895,14 +1893,14 @@
 		r = l.objs[pp.objidx].r
 		auxs = pp.auxs
 	} else {
-		var li int
+		var li uint32
 		r, li = l.toLocal(i)
 		auxs = r.Auxs(li)
 	}
 	for j := range auxs {
 		a := &auxs[j]
 		if a.Type() == goobj2.AuxFuncInfo {
-			b := r.Data(int(a.Sym().SymIdx))
+			b := r.Data(a.Sym().SymIdx)
 			return FuncInfo{l, r, b, auxs, goobj2.FuncInfoLengths{}}
 		}
 	}
@@ -1913,7 +1911,7 @@
 // Does not add non-package symbols yet, which will be done in LoadNonpkgSyms.
 // Does not read symbol data.
 // Returns the fingerprint of the object.
-func (l *Loader) Preload(syms *sym.Symbols, f *bio.Reader, lib *sym.Library, unit *sym.CompilationUnit, length int64) goobj2.FingerprintType {
+func (l *Loader) Preload(localSymVersion int, f *bio.Reader, lib *sym.Library, unit *sym.CompilationUnit, length int64) goobj2.FingerprintType {
 	roObject, readonly, err := f.Slice(uint64(length)) // TODO: no need to map blocks that are for tools only (e.g. RefName)
 	if err != nil {
 		log.Fatal("cannot read object file:", err)
@@ -1921,11 +1919,10 @@
 	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")
 	}
-	localSymVersion := syms.IncVersion()
 	pkgprefix := objabi.PathToPrefix(lib.Pkg) + "."
 	ndef := r.NSym()
 	nnonpkgdef := r.NNonpkgdef()
@@ -1952,9 +1949,9 @@
 
 // Preload symbols of given kind from an object.
 func (l *Loader) preloadSyms(r *oReader, kind int) {
-	ndef := r.NSym()
-	nnonpkgdef := r.NNonpkgdef()
-	var start, end int
+	ndef := uint32(r.NSym())
+	nnonpkgdef := uint32(r.NNonpkgdef())
+	var start, end uint32
 	switch kind {
 	case pkgDef:
 		start = 0
@@ -1965,11 +1962,14 @@
 	default:
 		panic("preloadSyms: bad kind")
 	}
-	l.growSyms(len(l.objSyms) + end - start)
-	l.growAttrBitmaps(len(l.objSyms) + end - start)
+	l.growAttrBitmaps(len(l.objSyms) + int(end-start))
+	needNameExpansion := r.NeedNameExpansion()
 	for i := start; i < end; i++ {
 		osym := r.Sym(i)
-		name := strings.Replace(osym.Name(r.Reader), "\"\".", r.pkgprefix, -1)
+		name := osym.Name(r.Reader)
+		if needNameExpansion {
+			name = strings.Replace(name, "\"\".", r.pkgprefix, -1)
+		}
 		v := abiToVer(osym.ABI(), r.version)
 		dupok := osym.Dupok()
 		gi, added := l.AddSym(name, v, r, i, kind, dupok, sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type())])
@@ -1992,11 +1992,6 @@
 				l.builtinSyms[bi] = gi
 			}
 		}
-		if strings.HasPrefix(name, "go.string.") ||
-			strings.HasPrefix(name, "gclocals·") ||
-			strings.HasPrefix(name, "runtime.gcbits.") {
-			l.SetAttrNotInSymbolTable(gi, true)
-		}
 		if a := osym.Align(); a != 0 {
 			l.SetSymAlign(gi, int32(a))
 		}
@@ -2006,19 +2001,24 @@
 // Add non-package symbols and references to external symbols (which are always
 // named).
 func (l *Loader) LoadNonpkgSyms(arch *sys.Arch) {
-	for _, o := range l.objs[1:] {
+	for _, o := range l.objs[goObjStart:] {
 		l.preloadSyms(o.r, nonPkgDef)
 	}
-	for _, o := range l.objs[1:] {
+	for _, o := range l.objs[goObjStart:] {
 		loadObjRefs(l, o.r, arch)
 	}
+	l.values = make([]int64, l.NSym(), l.NSym()+1000) // +1000 make some room for external symbols
 }
 
 func loadObjRefs(l *Loader, r *oReader, arch *sys.Arch) {
-	ndef := r.NSym() + r.NNonpkgdef()
-	for i, n := 0, r.NNonpkgref(); i < n; i++ {
+	ndef := uint32(r.NSym() + r.NNonpkgdef())
+	needNameExpansion := r.NeedNameExpansion()
+	for i, n := uint32(0), uint32(r.NNonpkgref()); i < n; i++ {
 		osym := r.Sym(ndef + i)
-		name := strings.Replace(osym.Name(r.Reader), "\"\".", r.pkgprefix, -1)
+		name := osym.Name(r.Reader)
+		if needNameExpansion {
+			name = strings.Replace(name, "\"\".", r.pkgprefix, -1)
+		}
 		v := abiToVer(osym.ABI(), r.version)
 		r.syms[ndef+i] = l.LookupOrCreateSym(name, v)
 		gi := r.syms[ndef+i]
@@ -2070,163 +2070,6 @@
 	}
 }
 
-// Load full contents.
-func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols, needReloc, needExtReloc bool) {
-	// create all Symbols first.
-	l.growSyms(l.NSym())
-	l.growSects(l.NSym())
-
-	if needReloc && len(l.extRelocs) != 0 {
-		// If needReloc is true, we are going to convert the loader's
-		// "internal" relocations to sym.Relocs. In this case, external
-		// relocations shouldn't be used.
-		panic("phase error")
-	}
-
-	nr := 0 // total number of sym.Reloc's we'll need
-	for _, o := range l.objs[1:] {
-		nr += loadObjSyms(l, syms, o.r, needReloc, needExtReloc)
-	}
-
-	// Make a first pass through the external symbols, making
-	// sure that each external symbol has a non-nil entry in
-	// l.Syms (note that relocations and symbol content will
-	// be copied in a later loop).
-	toConvert := make([]Sym, 0, len(l.payloads))
-	for _, i := range l.extReader.syms {
-		if !l.attrReachable.Has(i) {
-			continue
-		}
-		pp := l.getPayload(i)
-		if needReloc {
-			nr += len(pp.relocs)
-		}
-		if needExtReloc && int(i) < len(l.extRelocs) {
-			nr += len(l.extRelocs[i])
-		}
-		// create and install the sym.Symbol here so that l.Syms will
-		// be fully populated when we do relocation processing and
-		// outer/sub processing below. Note that once we do this,
-		// we'll need to get at the payload for a symbol with direct
-		// reference to l.payloads[] as opposed to calling l.getPayload().
-		s := l.allocSym(pp.name, 0)
-		l.installSym(i, s)
-		toConvert = append(toConvert, i)
-	}
-
-	// allocate a single large slab of relocations for all live symbols
-	if nr != 0 {
-		l.relocBatch = make([]sym.Reloc, nr)
-		if needExtReloc {
-			l.relocExtBatch = make([]sym.RelocExt, nr)
-		}
-	}
-
-	// convert payload-based external symbols into sym.Symbol-based
-	for _, i := range toConvert {
-
-		// Copy kind/size/value etc.
-		pp := l.payloads[l.extIndex(i)]
-		s := l.Syms[i]
-		s.Version = int16(pp.ver)
-		s.Type = pp.kind
-		s.Size = pp.size
-
-		// Copy relocations
-		if needReloc {
-			batch := l.relocBatch
-			s.R = batch[:len(pp.relocs):len(pp.relocs)]
-			l.relocBatch = batch[len(pp.relocs):]
-			relocs := l.Relocs(i)
-			l.convertRelocations(i, &relocs, s, false)
-		}
-		if needExtReloc {
-			l.convertExtRelocs(s, i)
-		}
-
-		// Copy data
-		s.P = pp.data
-
-		// Transfer over attributes.
-		l.migrateAttributes(i, s)
-	}
-
-	// load contents of defined symbols
-	for _, o := range l.objs[1:] {
-		loadObjFull(l, o.r, needReloc, needExtReloc)
-	}
-
-	// Sanity check: we should have consumed all batched allocations.
-	if len(l.relocBatch) != 0 || len(l.relocExtBatch) != 0 {
-		panic("batch allocation mismatch")
-	}
-
-	// Note: resolution of ABI aliases is now also handled in
-	// loader.convertRelocations, so once the host object loaders move
-	// completely to loader.Sym, we can remove the code below.
-
-	// Resolve ABI aliases for external symbols. This is only
-	// needed for internal cgo linking.
-	if needReloc {
-		for _, i := range l.extReader.syms {
-			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
-					}
-				}
-			}
-		}
-	}
-
-	// Free some memory.
-	// At this point we still need basic index mapping, and some fields of
-	// external symbol payloads, but not much else.
-	l.values = nil
-	l.symSects = nil
-	l.outdata = nil
-	l.itablink = nil
-	l.attrOnList = nil
-	l.attrLocal = nil
-	l.attrNotInSymbolTable = nil
-	l.attrVisibilityHidden = nil
-	l.attrDuplicateOK = nil
-	l.attrShared = nil
-	l.attrExternal = nil
-	l.attrReadOnly = nil
-	l.attrTopFrame = nil
-	l.attrSpecial = nil
-	l.attrCgoExportDynamic = nil
-	l.attrCgoExportStatic = nil
-	l.outer = nil
-	l.align = nil
-	l.dynimplib = nil
-	l.dynimpvers = nil
-	l.localentry = nil
-	l.extname = nil
-	l.elfType = nil
-	l.plt = nil
-	l.got = nil
-	l.dynid = nil
-	if needExtReloc { // converted to sym.Relocs, drop loader references
-		l.relocVariant = nil
-		l.extRelocs = nil
-	}
-
-	// Drop fields that are no longer needed.
-	for _, i := range l.extReader.syms {
-		pp := l.getPayload(i)
-		pp.name = ""
-		pp.auxs = nil
-		pp.data = nil
-		if needExtReloc {
-			pp.relocs = nil
-			pp.reltypes = nil
-		}
-	}
-}
-
 // ResolveABIAlias given a symbol returns the ABI alias target of that
 // symbol. If the sym in question is not an alias, the sym itself is
 // returned.
@@ -2245,227 +2088,6 @@
 	return target
 }
 
-// PropagateSymbolChangesBackToLoader is a temporary shim function
-// that copies over a given sym.Symbol into the equivalent representation
-// in the loader world. The intent is to enable converting a given
-// linker phase/pass from dealing with sym.Symbol's to a modernized
-// pass that works with loader.Sym, in cases where the "loader.Sym
-// wavefront" has not yet reached the pass in question. For such work
-// the recipe is to first call PropagateSymbolChangesBackToLoader(),
-// then exexute the pass working with the loader, then call
-// PropagateLoaderChangesToSymbols to copy the changes made by the
-// pass back to the sym.Symbol world.
-func (l *Loader) PropagateSymbolChangesBackToLoader() {
-
-	// For the moment we only copy symbol values, and we don't touch
-	// any new sym.Symbols created since loadlibfull() was run. This
-	// seems to be what's needed for DWARF gen.
-	for i := Sym(1); i < Sym(len(l.objSyms)); i++ {
-		s := l.Syms[i]
-		if s != nil {
-			if s.Value != l.SymValue(i) {
-				l.SetSymValue(i, s.Value)
-			}
-		}
-	}
-}
-
-// PropagateLoaderChangesToSymbols is a temporary shim function that
-// takes a list of loader.Sym symbols and works to copy their contents
-// and attributes over to a corresponding sym.Symbol. The parameter
-// anonVerReplacement specifies a version number for any new anonymous
-// symbols encountered on the list, when creating sym.Symbols for them
-// (or zero if we don't expect to encounter any new anon symbols). See
-// the PropagateSymbolChangesBackToLoader header comment for more
-// info.
-//
-// WARNING: this function is brittle and depends heavily on loader
-// implementation. A key problem with doing this is that as things
-// stand at the moment, some sym.Symbol contents/attributes are
-// populated only when converting from loader.Sym to sym.Symbol in
-// loadlibfull, meaning we may wipe out some information when copying
-// back.
-
-func (l *Loader) PropagateLoaderChangesToSymbols(toconvert []Sym, anonVerReplacement int) []*sym.Symbol {
-
-	result := []*sym.Symbol{}
-	relocfixup := []Sym{}
-
-	// Note: this loop needs to allow for the possibility that we may
-	// see "new" symbols on the 'toconvert' list that come from object
-	// files (for example, DWARF location lists), as opposed to just
-	// newly manufactured symbols (ex: DWARF section symbols such as
-	// ".debug_info").  This means that we have to be careful not to
-	// stomp on sym.Symbol attributes/content that was set up in
-	// in loadlibfull().
-
-	// Also note that in order for the relocation fixup to work, we
-	// have to do this in two passes -- one pass to create the symbols,
-	// and then a second fix up the relocations once all necessary
-	// sym.Symbols are created.
-
-	// First pass, symbol creation and symbol data fixup.
-	for _, cand := range toconvert {
-
-		sn := l.SymName(cand)
-		sv := l.SymVersion(cand)
-		st := l.SymType(cand)
-		if sv < 0 {
-			if anonVerReplacement == 0 {
-				panic("expected valid anon version replacement")
-			}
-			sv = anonVerReplacement
-		}
-
-		s := l.Syms[cand]
-
-		isnew := false
-		if sn == "" {
-			// Don't install anonymous symbols in the lookup tab.
-			if s == nil {
-				s = l.allocSym(sn, sv)
-				l.installSym(cand, s)
-			}
-			isnew = true
-		} else {
-			if s != nil {
-				// Already have a symbol for this -- it must be
-				// something that was previously processed by
-				// loadObjFull. Note that the symbol in question may
-				// or may not be in the name lookup map.
-			} else {
-				isnew = true
-				s = l.SymLookup(sn, sv)
-			}
-		}
-		result = append(result, s)
-
-		// Always copy these from new to old.
-		s.Value = l.SymValue(cand)
-		s.Type = st
-
-		// If the data for a symbol has increased in size, make sure
-		// we bring the new content across.
-		relfix := isnew
-		if isnew || len(l.Data(cand)) > len(s.P) {
-			s.P = l.Data(cand)
-			s.Size = int64(len(s.P))
-			relfix = true
-		}
-
-		// For 'new' symbols, copy other content.
-		if relfix {
-			relocfixup = append(relocfixup, cand)
-		}
-
-		// If new symbol, call a helper to migrate attributes.
-		// Otherwise touch only not-in-symbol-table, since there are
-		// some attrs that are only set up at the point where we
-		// convert loader.Sym to sym.Symbol.
-		if isnew {
-			l.migrateAttributes(cand, s)
-		} else {
-			if l.AttrNotInSymbolTable(cand) {
-				s.Attr.Set(sym.AttrNotInSymbolTable, true)
-			}
-		}
-	}
-
-	// Second pass to fix up relocations.
-	for _, cand := range relocfixup {
-		s := l.Syms[cand]
-		relocs := l.Relocs(cand)
-		if len(s.R) != relocs.Count() {
-			s.R = make([]sym.Reloc, relocs.Count())
-		}
-		l.convertRelocations(cand, &relocs, s, true)
-	}
-
-	return result
-}
-
-// 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) {
-	// 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. We do, however,
-	// add these symbols to the list of global symbols so that other future
-	// steps (like pclntab generation) can find these symbols if neceassary.
-	// 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.Version < 0 {
-			s.Version = int16(anonVerReplacement)
-		}
-	}
-
-	// Provide lookup functions for sym.Symbols.
-	l.SymLookup = func(name string, ver int) *sym.Symbol {
-		i := l.LookupOrCreateSym(name, ver)
-		if s := l.Syms[i]; s != nil {
-			return s
-		}
-		s := l.allocSym(name, ver)
-		l.installSym(i, s)
-		return s
-	}
-	syms.Lookup = l.SymLookup
-	syms.ROLookup = func(name string, ver int) *sym.Symbol {
-		i := l.Lookup(name, ver)
-		return l.Syms[i]
-	}
-}
-
-// allocSym allocates a new symbol backing.
-func (l *Loader) allocSym(name string, version int) *sym.Symbol {
-	batch := l.symBatch
-	if len(batch) == 0 {
-		batch = make([]sym.Symbol, 1000)
-	}
-	s := &batch[0]
-	l.symBatch = batch[1:]
-
-	s.Dynid = -1
-	s.Name = name
-	s.Version = int16(version)
-
-	return s
-}
-
-// installSym sets the underlying sym.Symbol for the specified sym index.
-func (l *Loader) installSym(i Sym, s *sym.Symbol) {
-	if s == nil {
-		panic("installSym nil symbol")
-	}
-	if l.Syms[i] != nil {
-		panic("sym already present in installSym")
-	}
-	l.Syms[i] = s
-	s.SymIdx = sym.LoaderSym(i)
-}
-
-// addNewSym adds a new sym.Symbol to the i-th index in the list of symbols.
-func (l *Loader) addNewSym(i Sym, name string, ver int, unit *sym.CompilationUnit, t sym.SymKind) *sym.Symbol {
-	s := l.allocSym(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
-	l.growSyms(int(i))
-	l.installSym(i, s)
-	return s
-}
-
 // TopLevelSym tests a symbol (by name and kind) to determine whether
 // the symbol first class sym (participating in the link) or is an
 // anonymous aux or sub-symbol containing some sub-part or payload of
@@ -2483,56 +2105,13 @@
 		return true
 	}
 	switch skind {
-	case sym.SDWARFINFO, sym.SDWARFRANGE, sym.SDWARFLOC, sym.SDWARFLINES, sym.SGOFUNC:
+	case sym.SDWARFFCN, sym.SDWARFABSFCN, sym.SDWARFTYPE, sym.SDWARFCONST, sym.SDWARFCUINFO, sym.SDWARFRANGE, sym.SDWARFLOC, sym.SDWARFLINES, sym.SGOFUNC:
 		return true
 	default:
 		return false
 	}
 }
 
-// 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, needReloc, needExtReloc bool) int {
-	nr := 0
-	for i, n := 0, r.NSym()+r.NNonpkgdef(); i < n; i++ {
-		gi := r.syms[i]
-		if r2, i2 := l.toLocal(gi); r2 != r || i2 != i {
-			continue // come from a different object
-		}
-		osym := r.Sym(i)
-		name := strings.Replace(osym.Name(r.Reader), "\"\".", r.pkgprefix, -1)
-		t := sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type())]
-
-		// Skip non-dwarf anonymous symbols (e.g. funcdata),
-		// since they will never be turned into sym.Symbols.
-		if !topLevelSym(name, t) {
-			continue
-		}
-		ver := abiToVer(osym.ABI(), r.version)
-		if t == sym.SXREF {
-			log.Fatalf("bad sxref")
-		}
-		if t == 0 {
-			log.Fatalf("missing type for %s in %s", name, r.unit.Lib)
-		}
-		if !l.attrReachable.Has(gi) && name != "runtime.addmoduledata" && name != "runtime.lastmoduledatap" {
-			// No need to load unreachable symbols.
-			// XXX reference to runtime.addmoduledata may be generated later by the linker in plugin mode.
-			continue
-		}
-
-		l.addNewSym(gi, name, ver, r.unit, t)
-		if needReloc {
-			nr += r.NReloc(i)
-		}
-		if needExtReloc && int(gi) < len(l.extRelocs) {
-			nr += len(l.extRelocs[gi])
-		}
-	}
-	return nr
-}
-
 // cloneToExternal takes the existing object file symbol (symIdx)
 // and creates a new external symbol payload that is a clone with
 // respect to name, version, type, relocations, etc. The idea here
@@ -2540,17 +2119,18 @@
 // a symbol originally discovered as part of an object file, it's
 // easier to do this if we make the updates to an external symbol
 // payload.
-// XXX maybe rename? makeExtPayload?
 func (l *Loader) cloneToExternal(symIdx Sym) {
 	if l.IsExternal(symIdx) {
 		panic("sym is already external, no need for clone")
 	}
-	l.growSyms(int(symIdx))
 
 	// Read the particulars from object.
 	r, li := l.toLocal(symIdx)
 	osym := r.Sym(li)
-	sname := strings.Replace(osym.Name(r.Reader), "\"\".", r.pkgprefix, -1)
+	sname := osym.Name(r.Reader)
+	if r.NeedNameExpansion() {
+		sname = strings.Replace(sname, "\"\".", r.pkgprefix, -1)
+	}
 	sver := abiToVer(osym.ABI(), r.version)
 	skind := sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type())]
 
@@ -2564,7 +2144,7 @@
 
 	// If this is a def, then copy the guts. We expect this case
 	// to be very rare (one case it may come up is with -X).
-	if li < (r.NSym() + r.NNonpkgdef()) {
+	if li < uint32(r.NSym()+r.NNonpkgdef()) {
 
 		// Copy relocations
 		relocs := l.Relocs(symIdx)
@@ -2586,22 +2166,11 @@
 	// Gotype, so as to propagate it to the new symbol.
 	auxs := r.Auxs(li)
 	pp.auxs = auxs
-loop:
-	for j := range auxs {
-		a := &auxs[j]
-		switch a.Type() {
-		case goobj2.AuxGotype:
-			pp.gotype = l.resolve(r, a.Sym())
-			break loop
-		default:
-			// nothing to do
-		}
-	}
 
 	// Install new payload to global index space.
 	// (This needs to happen at the end, as the accessors above
 	// need to access the old symbol content.)
-	l.objSyms[symIdx] = objSym{l.extReader, pi}
+	l.objSyms[symIdx] = objSym{l.extReader.objidx, uint32(pi)}
 	l.extReader.syms = append(l.extReader.syms, symIdx)
 }
 
@@ -2649,67 +2218,6 @@
 	l.SetAttrReadOnly(dst, l.AttrReadOnly(src))
 }
 
-// migrateAttributes copies over all of the attributes of symbol 'src' to
-// sym.Symbol 'dst'.
-func (l *Loader) migrateAttributes(src Sym, dst *sym.Symbol) {
-	dst.Value = l.SymValue(src)
-	dst.Align = l.SymAlign(src)
-	dst.Sect = l.SymSect(src)
-
-	dst.Attr.Set(sym.AttrReachable, l.AttrReachable(src))
-	dst.Attr.Set(sym.AttrOnList, l.AttrOnList(src))
-	dst.Attr.Set(sym.AttrLocal, l.AttrLocal(src))
-	dst.Attr.Set(sym.AttrNotInSymbolTable, l.AttrNotInSymbolTable(src))
-	dst.Attr.Set(sym.AttrNoSplit, l.IsNoSplit(src))
-	dst.Attr.Set(sym.AttrVisibilityHidden, l.AttrVisibilityHidden(src))
-	dst.Attr.Set(sym.AttrDuplicateOK, l.AttrDuplicateOK(src))
-	dst.Attr.Set(sym.AttrShared, l.AttrShared(src))
-	dst.Attr.Set(sym.AttrExternal, l.AttrExternal(src))
-	dst.Attr.Set(sym.AttrTopFrame, l.AttrTopFrame(src))
-	dst.Attr.Set(sym.AttrSpecial, l.AttrSpecial(src))
-	dst.Attr.Set(sym.AttrCgoExportDynamic, l.AttrCgoExportDynamic(src))
-	dst.Attr.Set(sym.AttrCgoExportStatic, l.AttrCgoExportStatic(src))
-	dst.Attr.Set(sym.AttrReadOnly, l.AttrReadOnly(src))
-
-	// Convert outer relationship
-	if outer, ok := l.outer[src]; ok {
-		dst.Outer = l.Syms[outer]
-	}
-
-	// Set sub-symbol attribute. See the comment on the AttrSubSymbol
-	// method for more on this, there is some tricky stuff here.
-	dst.Attr.Set(sym.AttrSubSymbol, l.outer[src] != 0 && l.sub[l.outer[src]] != 0)
-
-	// Copy over dynimplib, dynimpvers, extname.
-	if name, ok := l.extname[src]; ok {
-		dst.SetExtname(name)
-	}
-	if l.SymDynimplib(src) != "" {
-		dst.SetDynimplib(l.SymDynimplib(src))
-	}
-	if l.SymDynimpvers(src) != "" {
-		dst.SetDynimpvers(l.SymDynimpvers(src))
-	}
-
-	// Copy ELF type if set.
-	if et, ok := l.elfType[src]; ok {
-		dst.SetElfType(et)
-	}
-
-	// Copy pe objects values if set.
-	if plt, ok := l.plt[src]; ok {
-		dst.SetPlt(plt)
-	}
-	if got, ok := l.got[src]; ok {
-		dst.SetGot(got)
-	}
-
-	// Copy dynid
-	if dynid, ok := l.dynid[src]; ok {
-		dst.Dynid = dynid
-	}
-}
-
 // CreateExtSym creates a new external symbol with the specified name
 // without adding it to any lookup tables, returning a Sym index for it.
 func (l *Loader) CreateExtSym(name string, ver int) Sym {
@@ -2720,8 +2228,7 @@
 // without adding it to any lookup tables, returning a Sym index for it.
 func (l *Loader) CreateStaticSym(name string) Sym {
 	// 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.
+	// symbol so that it is not included in the name lookup table.
 	l.anonVersion--
 	return l.newExtSym(name, l.anonVersion)
 }
@@ -2733,144 +2240,6 @@
 	}
 }
 
-func loadObjFull(l *Loader, r *oReader, needReloc, needExtReloc bool) {
-	for i, n := 0, r.NSym()+r.NNonpkgdef(); i < n; i++ {
-		// A symbol may be a dup or overwritten. In this case, its
-		// content will actually be provided by a different object
-		// (to which its global index points). Skip those symbols.
-		gi := l.toGlobal(r, i)
-		if r2, i2 := l.toLocal(gi); r2 != r || i2 != i {
-			continue
-		}
-		s := l.Syms[gi]
-		if s == nil {
-			continue
-		}
-
-		l.migrateAttributes(gi, s)
-		// Be careful not to overwrite attributes set by the linker.
-		// Don't use the attributes from the object file.
-
-		osym := r.Sym(i)
-		size := osym.Siz()
-
-		// Symbol data
-		s.P = l.OutData(gi)
-
-		// Relocs
-		if needReloc {
-			relocs := l.relocs(r, i)
-			batch := l.relocBatch
-			s.R = batch[:relocs.Count():relocs.Count()]
-			l.relocBatch = batch[relocs.Count():]
-			l.convertRelocations(gi, &relocs, s, false)
-		}
-		if needExtReloc {
-			l.convertExtRelocs(s, gi)
-		}
-
-		// Aux symbol info
-		auxs := r.Auxs(i)
-		for j := range auxs {
-			a := &auxs[j]
-			switch a.Type() {
-			case goobj2.AuxFuncInfo, goobj2.AuxFuncdata, goobj2.AuxGotype:
-				// already handled
-			case goobj2.AuxDwarfInfo, goobj2.AuxDwarfLoc, goobj2.AuxDwarfRanges, goobj2.AuxDwarfLines:
-				// ignored for now
-			default:
-				panic("unknown aux type")
-			}
-		}
-
-		if s.Size < int64(size) {
-			s.Size = int64(size)
-		}
-	}
-}
-
-// convertRelocations takes a vector of loader.Reloc relocations and
-// translates them into an equivalent set of sym.Reloc relocations on
-// the symbol "dst", performing fixups along the way for ABI aliases,
-// etc. It is assumed that the caller has pre-allocated the dst symbol
-// relocations slice. If 'strict' is set, then this method will
-// panic if it finds a relocation targeting a nil symbol.
-func (l *Loader) convertRelocations(symIdx Sym, src *Relocs, dst *sym.Symbol, strict bool) {
-	for j := range dst.R {
-		r := src.At2(j)
-		rs := r.Sym()
-		sz := r.Siz()
-		rt := r.Type()
-		if rt == objabi.R_METHODOFF {
-			if l.attrReachable.Has(rs) {
-				rt = objabi.R_ADDROFF
-			} else {
-				sz = 0
-				rs = 0
-			}
-		}
-		if rt == objabi.R_WEAKADDROFF && !l.attrReachable.Has(rs) {
-			rs = 0
-			sz = 0
-		}
-		if rs != 0 && l.Syms[rs] != nil && l.Syms[rs].Type == sym.SABIALIAS {
-			rsrelocs := l.Relocs(rs)
-			rs = rsrelocs.At2(0).Sym()
-		}
-		if strict && rs != 0 && l.Syms[rs] == nil && rt != objabi.R_USETYPE {
-			panic("nil reloc target in convertRelocations")
-		}
-		dst.R[j] = sym.Reloc{
-			Off:  r.Off(),
-			Siz:  sz,
-			Type: rt,
-			Add:  r.Add(),
-			Sym:  l.Syms[rs],
-		}
-		if rv := l.RelocVariant(symIdx, j); rv != 0 {
-			dst.R[j].InitExt()
-			dst.R[j].Variant = rv
-		}
-	}
-}
-
-// Convert external relocations to sym.Relocs on symbol dst.
-func (l *Loader) convertExtRelocs(dst *sym.Symbol, src Sym) {
-	if int(src) >= len(l.extRelocs) {
-		return
-	}
-	extRelocs := l.extRelocs[src]
-	if len(extRelocs) == 0 {
-		return
-	}
-	if len(dst.R) != 0 {
-		panic("bad")
-	}
-
-	n := len(extRelocs)
-	batch := l.relocBatch
-	dst.R = batch[:n:n]
-	l.relocBatch = batch[n:]
-	relocs := l.Relocs(src)
-	for i := range dst.R {
-		er := &extRelocs[i]
-		sr := relocs.At2(er.Idx)
-		r := &dst.R[i]
-		r.RelocExt = &l.relocExtBatch[0]
-		l.relocExtBatch = l.relocExtBatch[1:]
-		r.Off = sr.Off()
-		r.Siz = sr.Siz()
-		r.Type = sr.Type()
-		r.Sym = l.Syms[l.ResolveABIAlias(sr.Sym())]
-		r.Add = sr.Add()
-		r.Xsym = l.Syms[er.Xsym]
-		r.Xadd = er.Xadd
-		if rv := l.RelocVariant(src, er.Idx); rv != 0 {
-			r.Variant = rv
-		}
-	}
-}
-
 // relocId is essentially a <S,R> tuple identifying the Rth
 // relocation of symbol S.
 type relocId struct {
@@ -2927,19 +2296,19 @@
 	return result
 }
 
-// AssignTextSymbolOrder populates the Textp2 slices within each
+// AssignTextSymbolOrder populates the Textp slices within each
 // library and compilation unit, insuring that packages are laid down
 // in dependency order (internal first, then everything else). Return value
 // is a slice of all text syms.
 func (l *Loader) AssignTextSymbolOrder(libs []*sym.Library, intlibs []bool, extsyms []Sym) []Sym {
 
-	// Library Textp2 lists should be empty at this point.
+	// Library Textp lists should be empty at this point.
 	for _, lib := range libs {
-		if len(lib.Textp2) != 0 {
-			panic("expected empty Textp2 slice for library")
+		if len(lib.Textp) != 0 {
+			panic("expected empty Textp slice for library")
 		}
-		if len(lib.DupTextSyms2) != 0 {
-			panic("expected empty DupTextSyms2 slice for library")
+		if len(lib.DupTextSyms) != 0 {
+			panic("expected empty DupTextSyms slice for library")
 		}
 	}
 
@@ -2950,21 +2319,21 @@
 	// call the regular addToTextp.
 	assignedToUnit := MakeBitmap(l.NSym() + 1)
 
-	// Start off textp2 with reachable external syms.
-	textp2 := []Sym{}
+	// Start off textp with reachable external syms.
+	textp := []Sym{}
 	for _, sym := range extsyms {
 		if !l.attrReachable.Has(sym) {
 			continue
 		}
-		textp2 = append(textp2, sym)
+		textp = append(textp, sym)
 	}
 
 	// Walk through all text symbols from Go object files and append
-	// them to their corresponding library's textp2 list.
-	for _, o := range l.objs[1:] {
+	// them to their corresponding library's textp list.
+	for _, o := range l.objs[goObjStart:] {
 		r := o.r
 		lib := r.unit.Lib
-		for i, n := 0, r.NSym()+r.NNonpkgdef(); i < n; i++ {
+		for i, n := uint32(0), uint32(r.NSym()+r.NNonpkgdef()); i < n; i++ {
 			gi := l.toGlobal(r, i)
 			if !l.attrReachable.Has(gi) {
 				continue
@@ -2980,15 +2349,15 @@
 				// We still need to record its presence in the current
 				// package, as the trampoline pass expects packages
 				// are laid out in dependency order.
-				lib.DupTextSyms2 = append(lib.DupTextSyms2, sym.LoaderSym(gi))
+				lib.DupTextSyms = append(lib.DupTextSyms, sym.LoaderSym(gi))
 				continue // symbol in different object
 			}
 			if dupok {
-				lib.DupTextSyms2 = append(lib.DupTextSyms2, sym.LoaderSym(gi))
+				lib.DupTextSyms = append(lib.DupTextSyms, sym.LoaderSym(gi))
 				continue
 			}
 
-			lib.Textp2 = append(lib.Textp2, sym.LoaderSym(gi))
+			lib.Textp = append(lib.Textp, sym.LoaderSym(gi))
 		}
 	}
 
@@ -2998,15 +2367,15 @@
 			if intlibs[idx] != doInternal {
 				continue
 			}
-			lists := [2][]sym.LoaderSym{lib.Textp2, lib.DupTextSyms2}
+			lists := [2][]sym.LoaderSym{lib.Textp, lib.DupTextSyms}
 			for i, list := range lists {
 				for _, s := range list {
 					sym := Sym(s)
 					if l.attrReachable.Has(sym) && !assignedToUnit.Has(sym) {
-						textp2 = append(textp2, sym)
+						textp = append(textp, sym)
 						unit := l.SymUnit(sym)
 						if unit != nil {
-							unit.Textp2 = append(unit.Textp2, s)
+							unit.Textp = append(unit.Textp, s)
 							assignedToUnit.Set(sym)
 						}
 						// Dupok symbols may be defined in multiple packages; the
@@ -3020,12 +2389,12 @@
 					}
 				}
 			}
-			lib.Textp2 = nil
-			lib.DupTextSyms2 = nil
+			lib.Textp = nil
+			lib.DupTextSyms = nil
 		}
 	}
 
-	return textp2
+	return textp
 }
 
 // ErrorReporter is a helper class for reporting errors.
@@ -3067,7 +2436,7 @@
 // For debugging.
 func (l *Loader) Dump() {
 	fmt.Println("objs")
-	for _, obj := range l.objs {
+	for _, obj := range l.objs[goObjStart:] {
 		if obj.r != nil {
 			fmt.Println(obj.i, obj.r.unit.Lib)
 		}
@@ -3080,15 +2449,7 @@
 		if l.IsExternal(i) {
 			pi = fmt.Sprintf("<ext %d>", l.extIndex(i))
 		}
-		var s *sym.Symbol
-		if int(i) < len(l.Syms) {
-			s = l.Syms[i]
-		}
-		if s != nil {
-			fmt.Println(i, s, s.Type, pi)
-		} else {
-			fmt.Println(i, l.SymName(i), "<not loaded>", pi)
-		}
+		fmt.Println(i, l.SymName(i), l.SymType(i), pi)
 	}
 	fmt.Println("symsByName")
 	for name, i := range l.symsByName[0] {
diff --git a/src/cmd/link/internal/loader/loader_test.go b/src/cmd/link/internal/loader/loader_test.go
index 60ef69a..8805a1e 100644
--- a/src/cmd/link/internal/loader/loader_test.go
+++ b/src/cmd/link/internal/loader/loader_test.go
@@ -19,7 +19,7 @@
 // do anything interesting with this symbol (such as look at its
 // data or relocations).
 func addDummyObjSym(t *testing.T, ldr *Loader, or *oReader, name string) Sym {
-	idx := len(ldr.objSyms)
+	idx := uint32(len(ldr.objSyms))
 	s, ok := ldr.AddSym(name, 0, or, idx, nonPkgDef, false, sym.SRODATA)
 	if !ok {
 		t.Errorf("AddrSym failed for '" + name + "'")
@@ -28,7 +28,7 @@
 }
 
 func mkLoader() *Loader {
-	edummy := func(s *sym.Symbol, str string, off int) {}
+	edummy := func(str string, off int) {}
 	er := ErrorReporter{}
 	ldr := NewLoader(0, edummy, &er)
 	er.ldr = ldr
@@ -72,7 +72,9 @@
 	// Suppose we create some more symbols, which triggers a grow.
 	// Make sure the symbol builder's payload pointer is valid,
 	// even across a grow.
-	ldr.growSyms(9999)
+	for i := 0; i < 9999; i++ {
+		ldr.CreateStaticSym("dummy")
+	}
 
 	// Check get/set symbol type
 	es3typ := sb3.Type()
diff --git a/src/cmd/link/internal/loader/symbolbuilder.go b/src/cmd/link/internal/loader/symbolbuilder.go
index 70adb36..b6e07db 100644
--- a/src/cmd/link/internal/loader/symbolbuilder.go
+++ b/src/cmd/link/internal/loader/symbolbuilder.go
@@ -9,7 +9,6 @@
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"cmd/link/internal/sym"
-	"fmt"
 	"sort"
 )
 
@@ -26,9 +25,6 @@
 func (l *Loader) MakeSymbolBuilder(name string) *SymbolBuilder {
 	// for now assume that any new sym is intended to be static
 	symIdx := l.CreateStaticSym(name)
-	if l.Syms[symIdx] != nil {
-		panic("can't build if sym.Symbol already present")
-	}
 	sb := &SymbolBuilder{l: l, symIdx: symIdx}
 	sb.extSymPayload = l.getPayload(symIdx)
 	return sb
@@ -47,14 +43,6 @@
 		// Create a clone with the same name/version/kind etc.
 		l.cloneToExternal(symIdx)
 	}
-	// Now that we're doing phase 2 DWARF generation using the loader
-	// but before the wavefront has reached dodata(), we can't have this
-	// assertion here. Commented out for now.
-	if false {
-		if l.Syms[symIdx] != nil {
-			panic(fmt.Sprintf("can't build if sym.Symbol %q already present", l.RawSymName(symIdx)))
-		}
-	}
 
 	// Construct updater and return.
 	sb := &SymbolBuilder{l: l, symIdx: symIdx}
@@ -363,7 +351,7 @@
 	r := sb.size
 	if sb.name == ".shstrtab" {
 		// FIXME: find a better mechanism for this
-		sb.l.elfsetstring(nil, str, int(r))
+		sb.l.elfsetstring(str, int(r))
 	}
 	sb.data = append(sb.data, str...)
 	sb.data = append(sb.data, 0)
diff --git a/src/cmd/link/internal/mips/asm.go b/src/cmd/link/internal/mips/asm.go
index 9710b9c..d0e0245 100644
--- a/src/cmd/link/internal/mips/asm.go
+++ b/src/cmd/link/internal/mips/asm.go
@@ -37,29 +37,21 @@
 	"cmd/link/internal/loader"
 	"cmd/link/internal/sym"
 	"debug/elf"
-	"fmt"
-	"log"
-	"sync"
 )
 
-func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
+func gentext(ctxt *ld.Link, ldr *loader.Loader) {
 	return
 }
 
-func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, 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 {
+func elfreloc1(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
 	ctxt.Out.Write32(uint32(sectoff))
 
 	elfsym := ld.ElfSymForReloc(ctxt, r.Xsym)
-	switch r.Type {
+	switch r.Type() {
 	default:
 		return false
 	case objabi.R_ADDR, objabi.R_DWARFSECREF:
-		if r.Siz != 4 {
+		if r.Siz() != 4 {
 			return false
 		}
 		ctxt.Out.Write32(uint32(elf.R_MIPS_32) | uint32(elfsym)<<8)
@@ -80,13 +72,13 @@
 	return
 }
 
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, 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 {
+func applyrel(arch *sys.Arch, ldr *loader.Loader, rt objabi.RelocType, off int32, s loader.Sym, val int64, t int64) int64 {
+	o := arch.ByteOrder.Uint32(ldr.OutData(s)[off:])
+	switch rt {
 	case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSTLS:
 		return int64(o&0xffff0000 | uint32(t)&0xffff)
 	case objabi.R_ADDRMIPSU:
@@ -98,133 +90,63 @@
 	}
 }
 
-func archreloc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
+func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (o int64, needExtReloc bool, ok bool) {
+	rs := r.Sym()
+	rs = ldr.ResolveABIAlias(rs)
 	if target.IsExternal() {
-		switch r.Type {
+		switch r.Type() {
 		default:
-			return val, false
+			return val, false, 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
+			rs, off := ld.FoldSubSymbolOffset(ldr, rs)
+			rr.Xadd = r.Add() + off
+			rst := ldr.SymType(rs)
+			if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && ldr.SymSect(rs) == nil {
+				ldr.Errorf(s, "missing section for %s", ldr.SymName(rs))
 			}
+			rr.Xsym = rs
+			return applyrel(target.Arch, ldr, r.Type(), r.Off(), s, val, rr.Xadd), true, true
 
-			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(target.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(target.Arch, r, s, val, r.Add), true
+			rr.Xsym = rs
+			rr.Xadd = r.Add()
+			return applyrel(target.Arch, ldr, r.Type(), r.Off(), s, val, rr.Xadd), true, 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(syms.GOT), true
+	const isOk = true
+	const noExtReloc = false
+	switch rt := r.Type(); rt {
 	case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSU:
-		t := ld.Symaddr(r.Sym) + r.Add
-		return applyrel(target.Arch, r, s, val, t), true
+		t := ldr.SymValue(rs) + r.Add()
+		return applyrel(target.Arch, ldr, rt, r.Off(), s, val, t), noExtReloc, isOk
 	case objabi.R_CALLMIPS, objabi.R_JMPMIPS:
-		t := ld.Symaddr(r.Sym) + r.Add
+		t := ldr.SymValue(rs) + r.Add()
 
 		if t&3 != 0 {
-			ld.Errorf(s, "direct call is not aligned: %s %x", r.Sym.Name, t)
+			ldr.Errorf(s, "direct call is not aligned: %s %x", ldr.SymName(rs), 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)
+		if (ldr.SymValue(s)+int64(r.Off())+4)&0xf0000000 != (t & 0xf0000000) {
+			ldr.Errorf(s, "direct call too far: %s %x", ldr.SymName(rs), t)
 		}
 
-		return applyrel(target.Arch, r, s, val, t), true
+		return applyrel(target.Arch, ldr, rt, r.Off(), s, val, t), noExtReloc, isOk
 	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
+		t := ldr.SymValue(rs) + r.Add() - 0x7000
 		if t < -32768 || t >= 32678 {
-			ld.Errorf(s, "TLS offset out of range %d", t)
+			ldr.Errorf(s, "TLS offset out of range %d", t)
 		}
-		return applyrel(target.Arch, r, s, val, t), true
+		return applyrel(target.Arch, ldr, rt, r.Off(), s, val, t), noExtReloc, isOk
 	}
 
-	return val, false
+	return val, false, false
 }
 
-func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
+func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc2, sym.RelocVariant, loader.Sym, int64) int64 {
 	return -1
 }
-
-func asmb(ctxt *ld.Link, _ *loader.Loader) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	var wg sync.WaitGroup
-	sect := ld.Segtext.Sections[0]
-	offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-	ld.WriteParallel(&wg, ld.Codeblk, ctxt, offset, sect.Vaddr, sect.Length)
-
-	for _, sect = range ld.Segtext.Sections[1:] {
-		offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, offset, sect.Vaddr, sect.Length)
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrodata.Fileoff, ld.Segrodata.Vaddr, ld.Segrodata.Filelen)
-	}
-
-	ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segdata.Fileoff, ld.Segdata.Vaddr, ld.Segdata.Filelen)
-
-	ld.WriteParallel(&wg, ld.Dwarfblk, ctxt, ld.Segdwarf.Fileoff, ld.Segdwarf.Vaddr, ld.Segdwarf.Filelen)
-	wg.Wait()
-}
-
-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.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))
-	}
-
-	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/link/internal/mips/obj.go b/src/cmd/link/internal/mips/obj.go
index f95c776..cc3cc43 100644
--- a/src/cmd/link/internal/mips/obj.go
+++ b/src/cmd/link/internal/mips/obj.go
@@ -49,15 +49,12 @@
 		Dwarfregsp: DWARFREGSP,
 		Dwarfreglr: DWARFREGLR,
 
-		Adddynrel:        adddynrel,
 		Archinit:         archinit,
 		Archreloc:        archreloc,
 		Archrelocvariant: archrelocvariant,
-		Asmb:             asmb,
-		Asmb2:            asmb2,
 		Elfreloc1:        elfreloc1,
 		Elfsetupplt:      elfsetupplt,
-		Gentext2:         gentext2,
+		Gentext:          gentext,
 		Machoreloc1:      machoreloc1,
 
 		Linuxdynld: "/lib/ld.so.1",
diff --git a/src/cmd/link/internal/mips64/asm.go b/src/cmd/link/internal/mips64/asm.go
index b48241b..dcca72c 100644
--- a/src/cmd/link/internal/mips64/asm.go
+++ b/src/cmd/link/internal/mips64/asm.go
@@ -37,19 +37,12 @@
 	"cmd/link/internal/loader"
 	"cmd/link/internal/sym"
 	"debug/elf"
-	"fmt"
-	"log"
-	"sync"
 )
 
-func gentext2(ctxt *ld.Link, ldr *loader.Loader) {}
+func gentext(ctxt *ld.Link, ldr *loader.Loader) {}
 
-func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
-	log.Fatalf("adddynrel not implemented")
-	return false
-}
+func elfreloc1(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
 
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
 	// mips64 ELF relocation (endian neutral)
 	//		offset	uint64
 	//		sym		uint32
@@ -66,11 +59,11 @@
 	ctxt.Out.Write8(0)
 	ctxt.Out.Write8(0)
 	ctxt.Out.Write8(0)
-	switch r.Type {
+	switch r.Type() {
 	default:
 		return false
 	case objabi.R_ADDR, objabi.R_DWARFSECREF:
-		switch r.Siz {
+		switch r.Siz() {
 		case 4:
 			ctxt.Out.Write8(uint8(elf.R_MIPS_32))
 		case 8:
@@ -97,180 +90,69 @@
 	return
 }
 
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool {
 	return false
 }
 
-func archreloc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
+func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (o int64, needExtReloc bool, ok bool) {
+	rs := r.Sym()
+	rs = ldr.ResolveABIAlias(rs)
 	if target.IsExternal() {
-		switch r.Type {
+		switch r.Type() {
 		default:
-			return val, false
+			return val, false, 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
+			rs, off := ld.FoldSubSymbolOffset(ldr, rs)
+			rr.Xadd = r.Add() + off
+			rst := ldr.SymType(rs)
+			if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && ldr.SymSect(rs) == nil {
+				ldr.Errorf(s, "missing section for %s", ldr.SymName(rs))
 			}
+			rr.Xsym = rs
+			return val, true, true
 
-			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
+			rr.Xsym = rs
+			rr.Xadd = r.Add()
+			return val, true, 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(syms.GOT), true
+	const isOk = true
+	const noExtReloc = false
+	switch r.Type() {
 	case objabi.R_ADDRMIPS,
 		objabi.R_ADDRMIPSU:
-		t := ld.Symaddr(r.Sym) + r.Add
-		o1 := target.Arch.ByteOrder.Uint32(s.P[r.Off:])
-		if r.Type == objabi.R_ADDRMIPS {
-			return int64(o1&0xffff0000 | uint32(t)&0xffff), true
+		t := ldr.SymValue(rs) + r.Add()
+		o1 := target.Arch.ByteOrder.Uint32(ldr.OutData(s)[r.Off():])
+		if r.Type() == objabi.R_ADDRMIPS {
+			return int64(o1&0xffff0000 | uint32(t)&0xffff), noExtReloc, isOk
 		}
-		return int64(o1&0xffff0000 | uint32((t+1<<15)>>16)&0xffff), true
+		return int64(o1&0xffff0000 | uint32((t+1<<15)>>16)&0xffff), noExtReloc, isOk
 	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
+		t := ldr.SymValue(rs) + r.Add() - 0x7000
 		if t < -32768 || t >= 32678 {
-			ld.Errorf(s, "TLS offset out of range %d", t)
+			ldr.Errorf(s, "TLS offset out of range %d", t)
 		}
-		o1 := target.Arch.ByteOrder.Uint32(s.P[r.Off:])
-		return int64(o1&0xffff0000 | uint32(t)&0xffff), true
+		o1 := target.Arch.ByteOrder.Uint32(ldr.OutData(s)[r.Off():])
+		return int64(o1&0xffff0000 | uint32(t)&0xffff), noExtReloc, isOk
 	case objabi.R_CALLMIPS,
 		objabi.R_JMPMIPS:
 		// Low 26 bits = (S + A) >> 2
-		t := ld.Symaddr(r.Sym) + r.Add
-		o1 := target.Arch.ByteOrder.Uint32(s.P[r.Off:])
-		return int64(o1&0xfc000000 | uint32(t>>2)&^0xfc000000), true
+		t := ldr.SymValue(rs) + r.Add()
+		o1 := target.Arch.ByteOrder.Uint32(ldr.OutData(s)[r.Off():])
+		return int64(o1&0xfc000000 | uint32(t>>2)&^0xfc000000), noExtReloc, isOk
 	}
 
-	return val, false
+	return val, false, false
 }
 
-func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
+func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc2, sym.RelocVariant, loader.Sym, int64) int64 {
 	return -1
 }
-
-func asmb(ctxt *ld.Link, _ *loader.Loader) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	var wg sync.WaitGroup
-	sect := ld.Segtext.Sections[0]
-	offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-	ld.WriteParallel(&wg, ld.Codeblk, ctxt, offset, sect.Vaddr, sect.Length)
-
-	for _, sect := range ld.Segtext.Sections[1:] {
-		offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, offset, sect.Vaddr, sect.Length)
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrodata.Fileoff, ld.Segrodata.Vaddr, ld.Segrodata.Filelen)
-	}
-
-	if ld.Segrelrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrelrodata.Fileoff, ld.Segrelrodata.Vaddr, ld.Segrelrodata.Filelen)
-	}
-
-	ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segdata.Fileoff, ld.Segdata.Vaddr, ld.Segdata.Filelen)
-
-	ld.WriteParallel(&wg, ld.Dwarfblk, ctxt, ld.Segdwarf.Fileoff, ld.Segdwarf.Vaddr, ld.Segdwarf.Filelen)
-	wg.Wait()
-}
-
-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.Write(ld.Elfstrdat)
-
-				if ctxt.LinkMode == ld.LinkExternal {
-					ld.Elfemitreloc(ctxt)
-				}
-			}
-
-		case objabi.Hplan9:
-			ld.Asmplan9sym(ctxt)
-
-			sym := ctxt.Syms.Lookup("pclntab", 0)
-			if sym != nil {
-				ld.Lcsize = int32(len(sym.P))
-				ctxt.Out.Write(sym.P)
-			}
-		}
-	}
-
-	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))
-	}
-
-	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/link/internal/mips64/obj.go b/src/cmd/link/internal/mips64/obj.go
index 5efa356..449a200 100644
--- a/src/cmd/link/internal/mips64/obj.go
+++ b/src/cmd/link/internal/mips64/obj.go
@@ -48,15 +48,12 @@
 		Minalign:         minAlign,
 		Dwarfregsp:       dwarfRegSP,
 		Dwarfreglr:       dwarfRegLR,
-		Adddynrel:        adddynrel,
 		Archinit:         archinit,
 		Archreloc:        archreloc,
 		Archrelocvariant: archrelocvariant,
-		Asmb:             asmb,
-		Asmb2:            asmb2,
 		Elfreloc1:        elfreloc1,
 		Elfsetupplt:      elfsetupplt,
-		Gentext2:         gentext2,
+		Gentext:          gentext,
 		Machoreloc1:      machoreloc1,
 
 		Linuxdynld:     "/lib64/ld64.so.1",
diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go
index b1c0873..ed086f0 100644
--- a/src/cmd/link/internal/ppc64/asm.go
+++ b/src/cmd/link/internal/ppc64/asm.go
@@ -41,10 +41,9 @@
 	"fmt"
 	"log"
 	"strings"
-	"sync"
 )
 
-func genplt2(ctxt *ld.Link, ldr *loader.Loader) {
+func genplt(ctxt *ld.Link, ldr *loader.Loader) {
 	// 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
@@ -94,7 +93,7 @@
 	// This assumes "case 1" from the ABI, where the caller needs
 	// us to save and restore the TOC pointer.
 	var stubs []loader.Sym
-	for _, s := range ctxt.Textp2 {
+	for _, s := range ctxt.Textp {
 		relocs := ldr.Relocs(s)
 		for i := 0; i < relocs.Count(); i++ {
 			r := relocs.At2(i)
@@ -104,7 +103,7 @@
 
 			// Reserve PLT entry and generate symbol
 			// resolver
-			addpltsym2(ctxt, ldr, r.Sym())
+			addpltsym(ctxt, ldr, r.Sym())
 
 			// Generate call stub. Important to note that we're looking
 			// up the stub using the same version as the parent symbol (s),
@@ -116,7 +115,7 @@
 			stub := ldr.CreateSymForUpdate(n, ldr.SymVersion(s))
 			if stub.Size() == 0 {
 				stubs = append(stubs, stub.Sym())
-				gencallstub2(ctxt, ldr, 1, stub, r.Sym())
+				gencallstub(ctxt, ldr, 1, stub, r.Sym())
 			}
 
 			// Update the relocation to use the call stub
@@ -138,10 +137,10 @@
 	// So when resolving the relocations to calls to the stubs,
 	// the addresses are known and trampolines can be inserted
 	// when necessary.
-	ctxt.Textp2 = append(stubs, ctxt.Textp2...)
+	ctxt.Textp = append(stubs, ctxt.Textp...)
 }
 
-func genaddmoduledata2(ctxt *ld.Link, ldr *loader.Loader) {
+func genaddmoduledata(ctxt *ld.Link, ldr *loader.Loader) {
 	initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt)
 	if initfunc == nil {
 		return
@@ -152,7 +151,7 @@
 	}
 
 	// addis r2, r12, .TOC.-func@ha
-	toc := ctxt.DotTOC2[0]
+	toc := ctxt.DotTOC[0]
 	rel1 := loader.Reloc{
 		Off:  0,
 		Size: 8,
@@ -207,26 +206,26 @@
 	o(0x4e800020)
 }
 
-func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
+func gentext(ctxt *ld.Link, ldr *loader.Loader) {
 	if ctxt.DynlinkingGo() {
-		genaddmoduledata2(ctxt, ldr)
+		genaddmoduledata(ctxt, ldr)
 	}
 
 	if ctxt.LinkMode == ld.LinkInternal {
-		genplt2(ctxt, ldr)
+		genplt(ctxt, ldr)
 	}
 }
 
 // Construct a call stub in stub that calls symbol targ via its PLT
 // entry.
-func gencallstub2(ctxt *ld.Link, ldr *loader.Loader, abicase int, stub *loader.SymbolBuilder, targ loader.Sym) {
+func gencallstub(ctxt *ld.Link, ldr *loader.Loader, abicase int, stub *loader.SymbolBuilder, targ loader.Sym) {
 	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.PLT2
+	plt := ctxt.PLT
 
 	stub.SetType(sym.STEXT)
 
@@ -267,16 +266,16 @@
 	stub.AddUint32(ctxt.Arch, 0x4e800420) // bctr
 }
 
-func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
+func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
 	if target.IsElf() {
-		return addelfdynrel2(target, ldr, syms, s, r, rIdx)
+		return addelfdynrel(target, ldr, syms, s, r, rIdx)
 	} else if target.IsAIX() {
-		return ld.Xcoffadddynrel2(target, ldr, syms, s, r, rIdx)
+		return ld.Xcoffadddynrel(target, ldr, syms, s, r, rIdx)
 	}
 	return false
 }
 
-func addelfdynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
+func addelfdynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
 	targ := r.Sym()
 	var targType sym.SymKind
 	if targ != 0 {
@@ -325,9 +324,9 @@
 		su.SetRelocType(rIdx, objabi.R_ADDR)
 		if targType == sym.SDYNIMPORT {
 			// These happen in .toc sections
-			ld.Adddynsym2(ldr, target, syms, targ)
+			ld.Adddynsym(ldr, target, syms, targ)
 
-			rela := ldr.MakeSymbolUpdater(syms.Rela2)
+			rela := ldr.MakeSymbolUpdater(syms.Rela)
 			rela.AddAddrPlus(target.Arch, s, int64(r.Off()))
 			rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(ldr.SymDynid(targ)), uint32(elf.R_PPC64_ADDR64)))
 			rela.AddUint64(target.Arch, uint64(r.Add()))
@@ -403,22 +402,22 @@
 	return false
 }
 
-func xcoffreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+func xcoffreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
 	rs := r.Xsym
 
 	emitReloc := func(v uint16, off uint64) {
 		out.Write64(uint64(sectoff) + off)
-		out.Write32(uint32(rs.Dynid))
+		out.Write32(uint32(ldr.SymDynid(rs)))
 		out.Write16(v)
 	}
 
 	var v uint16
-	switch r.Type {
+	switch r.Type() {
 	default:
 		return false
-	case objabi.R_ADDR:
+	case objabi.R_ADDR, objabi.R_DWARFSECREF:
 		v = ld.XCOFF_R_POS
-		if r.Siz == 4 {
+		if r.Siz() == 4 {
 			v |= 0x1F << 8
 		} else {
 			v |= 0x3F << 8
@@ -431,21 +430,21 @@
 	case objabi.R_POWER_TLS_LE:
 		emitReloc(ld.XCOFF_R_TLS_LE|0x0F<<8, 2)
 	case objabi.R_CALLPOWER:
-		if r.Siz != 4 {
+		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 {
+func elfreloc1(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, 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 {
+	rt := r.Type()
+	if rt == objabi.R_ADDR || rt == objabi.R_POWER_TLS || rt == objabi.R_CALLPOWER {
 	} else {
 		if ctxt.Arch.ByteOrder == binary.BigEndian {
 			sectoff += 2
@@ -454,11 +453,11 @@
 	ctxt.Out.Write64(uint64(sectoff))
 
 	elfsym := ld.ElfSymForReloc(ctxt, r.Xsym)
-	switch r.Type {
+	switch rt {
 	default:
 		return false
 	case objabi.R_ADDR, objabi.R_DWARFSECREF:
-		switch r.Siz {
+		switch r.Siz() {
 		case 4:
 			ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR32) | uint64(elfsym)<<32)
 		case 8:
@@ -507,7 +506,7 @@
 		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 {
+		if r.Siz() != 4 {
 			return false
 		}
 		ctxt.Out.Write64(uint64(elf.R_PPC64_REL24) | uint64(elfsym)<<32)
@@ -528,24 +527,24 @@
 	}
 }
 
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool {
 	return false
 }
 
 // Return the value of .TOC. for symbol s
-func symtoc(syms *ld.ArchSyms, s *sym.Symbol) int64 {
-	v := s.Version
-	if s.Outer != nil {
-		v = s.Outer.Version
+func symtoc(ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) int64 {
+	v := ldr.SymVersion(s)
+	if out := ldr.OuterSym(s); out != 0 {
+		v = ldr.SymVersion(out)
 	}
 
 	toc := syms.DotTOC[v]
-	if toc == nil {
-		ld.Errorf(s, "TOC-relative relocation in object without .TOC.")
+	if toc == 0 {
+		ldr.Errorf(s, "TOC-relative relocation in object without .TOC.")
 		return 0
 	}
 
-	return toc.Value
+	return ldr.SymValue(toc)
 }
 
 // archreloctoc relocates a TOC relative symbol.
@@ -553,36 +552,35 @@
 // 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(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) int64 {
+func archreloctoc(ldr *loader.Loader, target *ld.Target, syms *ld.ArchSyms, r loader.Reloc2, s loader.Sym, val int64) int64 {
+	rs := ldr.ResolveABIAlias(r.Sym())
 	if target.IsLinux() {
-		ld.Errorf(s, "archrelocaddr called for %s relocation\n", r.Sym.Name)
+		ldr.Errorf(s, "archrelocaddr called for %s relocation\n", ldr.SymName(rs))
 	}
 	var o1, o2 uint32
 
 	o1 = uint32(val >> 32)
 	o2 = uint32(val)
 
+	if !strings.HasPrefix(ldr.SymName(rs), "TOC.") {
+		ldr.Errorf(s, "archreloctoc called for a symbol without TOC anchor")
+	}
 	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")
-	}
+	relocs := ldr.Relocs(rs)
+	tarSym := ldr.ResolveABIAlias(relocs.At2(0).Sym())
 
-	if target.IsInternal() && tarSym != nil && tarSym.Attr.Reachable() && (tarSym.Sect.Seg == &ld.Segdata) {
-		t = ld.Symaddr(tarSym) + r.Add - syms.TOC.Value
+	if target.IsInternal() && tarSym != 0 && ldr.AttrReachable(tarSym) && ldr.SymSect(tarSym).Seg == &ld.Segdata {
+		t = ldr.SymValue(tarSym) + r.Add() - ldr.SymValue(syms.TOC)
 		// change ld to addi in the second instruction
 		o2 = (o2 & 0x03FF0000) | 0xE<<26
 		useAddi = true
 	} else {
-		t = ld.Symaddr(r.Sym) + r.Add - syms.TOC.Value
+		t = ldr.SymValue(rs) + r.Add() - ldr.SymValue(syms.TOC)
 	}
 
 	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)
+		ldr.Errorf(s, "TOC relocation for %s is too big to relocate %s: 0x%x", ldr.SymName(s), rs, t)
 	}
 
 	if t&0x8000 != 0 {
@@ -591,13 +589,13 @@
 
 	o1 |= uint32((t >> 16) & 0xFFFF)
 
-	switch r.Type {
+	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))
+				ldr.Errorf(s, "bad DS reloc for %s: %d", ldr.SymName(s), ldr.SymValue(rs))
 			}
 			o2 |= uint32(t) & 0xFFFC
 		}
@@ -610,9 +608,10 @@
 
 // archrelocaddr relocates a symbol address.
 // This code is for AIX only.
-func archrelocaddr(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) int64 {
+func archrelocaddr(ldr *loader.Loader, target *ld.Target, syms *ld.ArchSyms, r loader.Reloc2, s loader.Sym, val int64) int64 {
+	rs := ldr.ResolveABIAlias(r.Sym())
 	if target.IsAIX() {
-		ld.Errorf(s, "archrelocaddr called for %s relocation\n", r.Sym.Name)
+		ldr.Errorf(s, "archrelocaddr called for %s relocation\n", ldr.SymName(rs))
 	}
 	var o1, o2 uint32
 	if target.IsBigEndian() {
@@ -630,22 +629,22 @@
 	// 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
+	t := ldr.SymAddr(rs) + 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))
+		ldr.Errorf(s, "relocation for %s is too big (>=2G): 0x%x", ldr.SymName(s), ldr.SymValue(rs))
 	}
 	if t&0x8000 != 0 {
 		t += 0x10000
 	}
 
-	switch r.Type {
+	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))
+			ldr.Errorf(s, "bad DS reloc for %s: %d", ldr.SymName(s), ldr.SymValue(rs))
 		}
 		o2 |= uint32(t) & 0xfffc
 	default:
@@ -799,119 +798,114 @@
 	tramp.SetData(P)
 }
 
-func archreloc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
+func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (relocatedOffset int64, needExtReloc bool, ok bool) {
+	needExternal := false
+	rs := ldr.ResolveABIAlias(r.Sym())
 	if target.IsExternal() {
 		// On AIX, relocations (except TLS ones) must be also done to the
 		// value with the current addresses.
-		switch r.Type {
+		switch r.Type() {
 		default:
 			if target.IsAIX() {
-				return val, false
+				return val, needExternal, 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
+			needExternal = true
+			rr.Xadd = r.Add()
+			rr.Xsym = rs
+			return val, needExternal, 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
+			needExternal = true
 
 			// 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
+			rs, off := ld.FoldSubSymbolOffset(ldr, rs)
+			rr.Xadd = r.Add() + off
+			rst := ldr.SymType(rs)
+			if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && rst != sym.SUNDEFEXT && ldr.SymSect(rs) == nil {
+				ldr.Errorf(s, "missing section for %s", ldr.SymName(rs))
 			}
-
-			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
+			rr.Xsym = rs
 
 			if !target.IsAIX() {
-				return val, true
+				return val, needExternal, true
 			}
 		case objabi.R_CALLPOWER:
-			r.Done = false
-			r.Xsym = r.Sym
-			r.Xadd = r.Add
+			needExternal = true
+			rr.Xsym = rs
+			rr.Xadd = r.Add()
 			if !target.IsAIX() {
-				return val, true
+				return val, needExternal, 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(syms.GOT), true
+	switch r.Type() {
 	case objabi.R_ADDRPOWER_TOCREL, objabi.R_ADDRPOWER_TOCREL_DS:
-		return archreloctoc(target, syms, r, s, val), true
+		return archreloctoc(ldr, target, syms, r, s, val), needExternal, true
 	case objabi.R_ADDRPOWER, objabi.R_ADDRPOWER_DS:
-		return archrelocaddr(target, syms, r, s, val), true
+		return archrelocaddr(ldr, target, syms, r, s, val), needExternal, 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))
+		t := ldr.SymValue(rs) + r.Add() - (ldr.SymValue(s) + int64(r.Off()))
 
 		if t&3 != 0 {
-			ld.Errorf(s, "relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
+			ldr.Errorf(s, "relocation for %s+%d is not aligned: %d", ldr.SymName(rs), 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)
+			ldr.Errorf(s, "direct call too far: %s %x", ldr.SymName(rs), t)
 		}
-		return val | int64(uint32(t)&^0xfc000003), true
+		return val | int64(uint32(t)&^0xfc000003), needExternal, true
 	case objabi.R_POWER_TOC: // S + A - .TOC.
-		return ld.Symaddr(r.Sym) + r.Add - symtoc(syms, s), true
+		return ldr.SymValue(rs) + r.Add() - symtoc(ldr, syms, s), needExternal, 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
+		v := ldr.SymValue(rs) - 0x7000
 		if target.IsAIX() {
 			// 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)
+			ldr.Errorf(s, "TLS offset out of range %d", v)
 		}
-		return (val &^ 0xffff) | (v & 0xffff), true
+		return (val &^ 0xffff) | (v & 0xffff), needExternal, true
 	}
 
-	return val, false
+	return val, needExternal, false
 }
 
-func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-	switch r.Variant & sym.RV_TYPE_MASK {
+func archrelocvariant(target *ld.Target, ldr *loader.Loader, r loader.Reloc2, rv sym.RelocVariant, s loader.Sym, t int64) (relocatedOffset int64) {
+	rs := ldr.ResolveABIAlias(r.Sym())
+	switch rv & sym.RV_TYPE_MASK {
 	default:
-		ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
+		ldr.Errorf(s, "unexpected relocation variant %d", rv)
 		fallthrough
 
 	case sym.RV_NONE:
 		return t
 
 	case sym.RV_POWER_LO:
-		if r.Variant&sym.RV_CHECK_OVERFLOW != 0 {
+		if rv&sym.RV_CHECK_OVERFLOW != 0 {
 			// Whether to check for signed or unsigned
 			// overflow depends on the instruction
 			var o1 uint32
 			if target.IsBigEndian() {
-				o1 = binary.BigEndian.Uint32(s.P[r.Off-2:])
+				o1 = binary.BigEndian.Uint32(ldr.Data(s)[r.Off()-2:])
 			} else {
-				o1 = binary.LittleEndian.Uint32(s.P[r.Off:])
+				o1 = binary.LittleEndian.Uint32(ldr.Data(s)[r.Off():])
 			}
 			switch o1 >> 26 {
 			case 24, // ori
@@ -938,14 +932,14 @@
 	case sym.RV_POWER_HI:
 		t >>= 16
 
-		if r.Variant&sym.RV_CHECK_OVERFLOW != 0 {
+		if rv&sym.RV_CHECK_OVERFLOW != 0 {
 			// Whether to check for signed or unsigned
 			// overflow depends on the instruction
 			var o1 uint32
 			if target.IsBigEndian() {
-				o1 = binary.BigEndian.Uint32(s.P[r.Off-2:])
+				o1 = binary.BigEndian.Uint32(ldr.Data(s)[r.Off()-2:])
 			} else {
-				o1 = binary.LittleEndian.Uint32(s.P[r.Off:])
+				o1 = binary.LittleEndian.Uint32(ldr.Data(s)[r.Off():])
 			}
 			switch o1 >> 26 {
 			case 25, // oris
@@ -967,40 +961,40 @@
 	case sym.RV_POWER_DS:
 		var o1 uint32
 		if target.IsBigEndian() {
-			o1 = uint32(binary.BigEndian.Uint16(s.P[r.Off:]))
+			o1 = uint32(binary.BigEndian.Uint16(ldr.Data(s)[r.Off():]))
 		} else {
-			o1 = uint32(binary.LittleEndian.Uint16(s.P[r.Off:]))
+			o1 = uint32(binary.LittleEndian.Uint16(ldr.Data(s)[r.Off():]))
 		}
 		if t&3 != 0 {
-			ld.Errorf(s, "relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
+			ldr.Errorf(s, "relocation for %s+%d is not aligned: %d", ldr.SymName(rs), r.Off(), t)
 		}
-		if (r.Variant&sym.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t {
+		if (rv&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)
+	ldr.Errorf(s, "relocation for %s+%d is too big: %d", ldr.SymName(rs), r.Off(), t)
 	return t
 }
 
-func addpltsym2(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym) {
+func addpltsym(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym) {
 	if ldr.SymPlt(s) >= 0 {
 		return
 	}
 
-	ld.Adddynsym2(ldr, &ctxt.Target, &ctxt.ArchSyms, s)
+	ld.Adddynsym(ldr, &ctxt.Target, &ctxt.ArchSyms, s)
 
 	if ctxt.IsELF {
-		plt := ldr.MakeSymbolUpdater(ctxt.PLT2)
-		rela := ldr.MakeSymbolUpdater(ctxt.RelaPLT2)
+		plt := ldr.MakeSymbolUpdater(ctxt.PLT)
+		rela := ldr.MakeSymbolUpdater(ctxt.RelaPLT)
 		if plt.Size() == 0 {
 			panic("plt is not set up")
 		}
 
 		// Create the glink resolver if necessary
-		glink := ensureglinkresolver2(ctxt, ldr)
+		glink := ensureglinkresolver(ctxt, ldr)
 
 		// Write symbol resolver stub (just a branch to the
 		// glink resolver stub)
@@ -1032,7 +1026,7 @@
 }
 
 // Generate the glink resolver stub if necessary and return the .glink section
-func ensureglinkresolver2(ctxt *ld.Link, ldr *loader.Loader) *loader.SymbolBuilder {
+func ensureglinkresolver(ctxt *ld.Link, ldr *loader.Loader) *loader.SymbolBuilder {
 	gs := ldr.LookupOrCreateSym(".glink", 0)
 	glink := ldr.MakeSymbolUpdater(gs)
 	if glink.Size() != 0 {
@@ -1061,7 +1055,7 @@
 	glink.AddUint32(ctxt.Arch, 0x7800f082) // srdi r0,r0,2
 
 	// r11 = address of the first byte of the PLT
-	glink.AddSymRef(ctxt.Arch, ctxt.PLT2, 0, objabi.R_ADDRPOWER, 8)
+	glink.AddSymRef(ctxt.Arch, ctxt.PLT, 0, objabi.R_ADDRPOWER, 8)
 
 	glink.AddUint32(ctxt.Arch, 0x3d600000) // addis r11,0,.plt@ha
 	glink.AddUint32(ctxt.Arch, 0x396b0000) // addi r11,r11,.plt@l
@@ -1080,121 +1074,8 @@
 
 	// Add DT_PPC64_GLINK .dynamic entry, which points to 32 bytes
 	// before the first symbol resolver stub.
-	du := ldr.MakeSymbolUpdater(ctxt.Dynamic2)
-	ld.Elfwritedynentsymplus2(ctxt, du, ld.DT_PPC64_GLINK, glink.Sym(), glink.Size()-32)
+	du := ldr.MakeSymbolUpdater(ctxt.Dynamic)
+	ld.Elfwritedynentsymplus(ctxt, du, ld.DT_PPC64_GLINK, glink.Sym(), glink.Size()-32)
 
 	return glink
 }
-
-func asmb(ctxt *ld.Link, _ *loader.Loader) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	var wg sync.WaitGroup
-	for _, sect := range ld.Segtext.Sections {
-		offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-		// Handle additional text sections with Codeblk
-		if sect.Name == ".text" {
-			ld.WriteParallel(&wg, ld.Codeblk, ctxt, offset, sect.Vaddr, sect.Length)
-		} else {
-			ld.WriteParallel(&wg, ld.Datblk, ctxt, offset, sect.Vaddr, sect.Length)
-		}
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrodata.Fileoff, ld.Segrodata.Vaddr, ld.Segrodata.Filelen)
-	}
-
-	if ld.Segrelrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrelrodata.Fileoff, ld.Segrelrodata.Vaddr, ld.Segrelrodata.Filelen)
-	}
-
-	ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segdata.Fileoff, ld.Segdata.Vaddr, ld.Segdata.Filelen)
-
-	ld.WriteParallel(&wg, ld.Dwarfblk, ctxt, ld.Segdwarf.Fileoff, ld.Segdwarf.Vaddr, ld.Segdwarf.Filelen)
-	wg.Wait()
-}
-
-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.Write(ld.Elfstrdat)
-
-				if ctxt.LinkMode == ld.LinkExternal {
-					ld.Elfemitreloc(ctxt)
-				}
-			}
-
-		case objabi.Hplan9:
-			ld.Asmplan9sym(ctxt)
-
-			sym := ctxt.Syms.Lookup("pclntab", 0)
-			if sym != nil {
-				ld.Lcsize = int32(len(sym.P))
-				ctxt.Out.Write(sym.P)
-			}
-
-		case objabi.Haix:
-			// symtab must be added once sections have been created in ld.Asmbxcoff
-		}
-	}
-
-	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))
-	}
-
-	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/link/internal/ppc64/obj.go b/src/cmd/link/internal/ppc64/obj.go
index 3e1d0a1..8a94f9a 100644
--- a/src/cmd/link/internal/ppc64/obj.go
+++ b/src/cmd/link/internal/ppc64/obj.go
@@ -43,21 +43,20 @@
 	}
 
 	theArch := ld.Arch{
-		Funcalign:  funcAlign,
-		Maxalign:   maxAlign,
-		Minalign:   minAlign,
-		Dwarfregsp: dwarfRegSP,
-		Dwarfreglr: dwarfRegLR,
+		Funcalign:       funcAlign,
+		Maxalign:        maxAlign,
+		Minalign:        minAlign,
+		Dwarfregsp:      dwarfRegSP,
+		Dwarfreglr:      dwarfRegLR,
+		WriteTextBlocks: true,
 
-		Adddynrel2:       adddynrel2,
+		Adddynrel:        adddynrel,
 		Archinit:         archinit,
 		Archreloc:        archreloc,
 		Archrelocvariant: archrelocvariant,
-		Asmb:             asmb,
-		Asmb2:            asmb2,
 		Elfreloc1:        elfreloc1,
 		Elfsetupplt:      elfsetupplt,
-		Gentext2:         gentext2,
+		Gentext:          gentext,
 		Trampoline:       trampoline,
 		Machoreloc1:      machoreloc1,
 		Xcoffreloc1:      xcoffreloc1,
diff --git a/src/cmd/link/internal/riscv64/asm.go b/src/cmd/link/internal/riscv64/asm.go
index 5183de8..7bc511c 100644
--- a/src/cmd/link/internal/riscv64/asm.go
+++ b/src/cmd/link/internal/riscv64/asm.go
@@ -13,23 +13,13 @@
 	"cmd/link/internal/sym"
 	"fmt"
 	"log"
-	"sync"
 )
 
-func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
+func gentext(ctxt *ld.Link, ldr *loader.Loader) {
 }
 
-func adddynrela(target *ld.Target, syms *ld.ArchSyms, rel *sym.Symbol, s *sym.Symbol, r *sym.Reloc) {
-	log.Fatalf("adddynrela not implemented")
-}
-
-func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, 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")
+func elfreloc1(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
+	log.Fatalf("elfreloc2")
 	return false
 }
 
@@ -37,48 +27,50 @@
 	log.Fatalf("elfsetuplt")
 }
 
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool {
 	log.Fatalf("machoreloc1 not implemented")
 	return false
 }
 
-func archreloc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-	switch r.Type {
+func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (o int64, needExtReloc bool, ok bool) {
+	rs := r.Sym()
+	rs = ldr.ResolveABIAlias(rs)
+	switch r.Type() {
 	case objabi.R_CALLRISCV:
 		// Nothing to do.
-		return val, true
+		return val, false, 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
+		pc := ldr.SymValue(s) + int64(r.Off())
+		off := ldr.SymValue(rs) + 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)
+			ldr.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)
+			ldr.Errorf(s, "cannot encode R_RISCV_PCREL_ AUIPC relocation offset for %s: %v", ldr.SymName(rs), err)
 		}
 
 		var secondImm, secondImmMask int64
-		switch r.Type {
+		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)
+				ldr.Errorf(s, "cannot encode R_RISCV_PCREL_ITYPE I-type instruction relocation offset for %s: %v", ldr.SymName(rs), 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)
+				ldr.Errorf(s, "cannot encode R_RISCV_PCREL_STYPE S-type instruction relocation offset for %s: %v", ldr.SymName(rs), err)
 			}
 		default:
-			panic(fmt.Sprintf("Unknown relocation type: %v", r.Type))
+			panic(fmt.Sprintf("Unknown relocation type: %v", r.Type()))
 		}
 
 		auipc := int64(uint32(val))
@@ -87,82 +79,13 @@
 		auipc = (auipc &^ riscv.UTypeImmMask) | int64(uint32(auipcImm))
 		second = (second &^ secondImmMask) | int64(uint32(secondImm))
 
-		return second<<32 | auipc, true
+		return second<<32 | auipc, false, true
 	}
 
-	return val, false
+	return val, false, false
 }
 
-func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
+func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc2, sym.RelocVariant, loader.Sym, int64) int64 {
 	log.Fatalf("archrelocvariant")
 	return -1
 }
-
-func asmb(ctxt *ld.Link, _ *loader.Loader) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	var wg sync.WaitGroup
-	sect := ld.Segtext.Sections[0]
-	offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-	ld.WriteParallel(&wg, ld.Codeblk, ctxt, offset, sect.Vaddr, sect.Length)
-
-	for _, sect := range ld.Segtext.Sections[1:] {
-		offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, offset, sect.Vaddr, sect.Length)
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrodata.Fileoff, ld.Segrodata.Vaddr, ld.Segrodata.Filelen)
-	}
-
-	if ld.Segrelrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrelrodata.Fileoff, ld.Segrelrodata.Vaddr, ld.Segrelrodata.Filelen)
-	}
-
-	ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segdata.Fileoff, ld.Segdata.Vaddr, ld.Segdata.Filelen)
-
-	ld.WriteParallel(&wg, ld.Dwarfblk, ctxt, ld.Segdwarf.Fileoff, ld.Segdwarf.Vaddr, ld.Segdwarf.Filelen)
-	wg.Wait()
-}
-
-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.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")
-	}
-
-	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/link/internal/riscv64/obj.go b/src/cmd/link/internal/riscv64/obj.go
index 4fa0ebe..e66d3cd 100644
--- a/src/cmd/link/internal/riscv64/obj.go
+++ b/src/cmd/link/internal/riscv64/obj.go
@@ -20,15 +20,12 @@
 		Dwarfregsp: dwarfRegSP,
 		Dwarfreglr: dwarfRegLR,
 
-		Adddynrel:        adddynrel,
 		Archinit:         archinit,
 		Archreloc:        archreloc,
 		Archrelocvariant: archrelocvariant,
-		Asmb:             asmb,
-		Asmb2:            asmb2,
 		Elfreloc1:        elfreloc1,
 		Elfsetupplt:      elfsetupplt,
-		Gentext2:         gentext2,
+		Gentext:          gentext,
 		Machoreloc1:      machoreloc1,
 
 		Linuxdynld: "/lib/ld.so.1",
diff --git a/src/cmd/link/internal/s390x/asm.go b/src/cmd/link/internal/s390x/asm.go
index 2115b5f..11406ee 100644
--- a/src/cmd/link/internal/s390x/asm.go
+++ b/src/cmd/link/internal/s390x/asm.go
@@ -37,8 +37,6 @@
 	"cmd/link/internal/loader"
 	"cmd/link/internal/sym"
 	"debug/elf"
-	"fmt"
-	"sync"
 )
 
 // gentext generates assembly to append the local moduledata to the global
@@ -51,7 +49,7 @@
 //	undef
 //
 // The job of appending the moduledata is delegated to runtime.addmoduledata.
-func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
+func gentext(ctxt *ld.Link, ldr *loader.Loader) {
 	initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt)
 	if initfunc == nil {
 		return
@@ -60,7 +58,7 @@
 	// larl %r2, <local.moduledata>
 	initfunc.AddUint8(0xc0)
 	initfunc.AddUint8(0x20)
-	initfunc.AddSymRef(ctxt.Arch, ctxt.Moduledata2, 6, objabi.R_PCREL, 4)
+	initfunc.AddSymRef(ctxt.Arch, ctxt.Moduledata, 6, objabi.R_PCREL, 4)
 	r1 := initfunc.Relocs()
 	ldr.SetRelocVariant(initfunc.Sym(), r1.Count()-1, sym.RV_390_DBL)
 
@@ -75,7 +73,7 @@
 	initfunc.AddUint32(ctxt.Arch, 0)
 }
 
-func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
+func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
 	targ := r.Sym()
 	var targType sym.SymKind
 	if targ != 0 {
@@ -136,8 +134,8 @@
 		ldr.SetRelocVariant(s, rIdx, sym.RV_390_DBL)
 		su.SetRelocAdd(rIdx, r.Add()+int64(r.Siz()))
 		if targType == sym.SDYNIMPORT {
-			addpltsym2(target, ldr, syms, targ)
-			r.SetSym(syms.PLT2)
+			addpltsym(target, ldr, syms, targ)
+			r.SetSym(syms.PLT)
 			su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymPlt(targ)))
 		}
 		return true
@@ -148,8 +146,8 @@
 		su.SetRelocType(rIdx, objabi.R_PCREL)
 		su.SetRelocAdd(rIdx, r.Add()+int64(r.Siz()))
 		if targType == sym.SDYNIMPORT {
-			addpltsym2(target, ldr, syms, targ)
-			r.SetSym(syms.PLT2)
+			addpltsym(target, ldr, syms, targ)
+			r.SetSym(syms.PLT)
 			su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymPlt(targ)))
 		}
 		return true
@@ -181,7 +179,7 @@
 	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTPC):
 		su := ldr.MakeSymbolUpdater(s)
 		su.SetRelocType(rIdx, objabi.R_PCREL)
-		r.SetSym(syms.GOT2)
+		r.SetSym(syms.GOT)
 		su.SetRelocAdd(rIdx, r.Add()+int64(r.Siz()))
 		return true
 
@@ -200,16 +198,16 @@
 		su := ldr.MakeSymbolUpdater(s)
 		su.SetRelocType(rIdx, objabi.R_PCREL)
 		ldr.SetRelocVariant(s, rIdx, sym.RV_390_DBL)
-		r.SetSym(syms.GOT2)
+		r.SetSym(syms.GOT)
 		su.SetRelocAdd(rIdx, r.Add()+int64(r.Siz()))
 		return true
 
 	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTENT):
-		addgotsym2(target, ldr, syms, targ)
+		ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_390_GLOB_DAT))
 		su := ldr.MakeSymbolUpdater(s)
 		su.SetRelocType(rIdx, objabi.R_PCREL)
 		ldr.SetRelocVariant(s, rIdx, sym.RV_390_DBL)
-		r.SetSym(syms.GOT2)
+		r.SetSym(syms.GOT)
 		su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ))+int64(r.Siz()))
 		return true
 	}
@@ -221,15 +219,17 @@
 	return false
 }
 
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
+func elfreloc1(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
 	ctxt.Out.Write64(uint64(sectoff))
 
 	elfsym := ld.ElfSymForReloc(ctxt, r.Xsym)
-	switch r.Type {
+	siz := r.Siz()
+	xst := ldr.SymType(r.Xsym)
+	switch r.Type() {
 	default:
 		return false
 	case objabi.R_TLS_LE:
-		switch r.Siz {
+		switch siz {
 		default:
 			return false
 		case 4:
@@ -240,14 +240,14 @@
 			ctxt.Out.Write64(uint64(elf.R_390_TLS_LE64) | uint64(elfsym)<<32)
 		}
 	case objabi.R_TLS_IE:
-		switch r.Siz {
+		switch siz {
 		default:
 			return false
 		case 4:
 			ctxt.Out.Write64(uint64(elf.R_390_TLS_IEENT) | uint64(elfsym)<<32)
 		}
 	case objabi.R_ADDR, objabi.R_DWARFSECREF:
-		switch r.Siz {
+		switch siz {
 		default:
 			return false
 		case 4:
@@ -256,30 +256,31 @@
 			ctxt.Out.Write64(uint64(elf.R_390_64) | uint64(elfsym)<<32)
 		}
 	case objabi.R_GOTPCREL:
-		if r.Siz == 4 {
+		if 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
+		rVariant := ldr.RelocVariant(s, r.Idx)
+		isdbl := rVariant&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 {
+		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 xst == sym.SDYNIMPORT && (ldr.SymElfType(r.Xsym) == elf.STT_FUNC || r.Type() == objabi.R_CALL) {
 			if isdbl {
-				switch r.Siz {
+				switch siz {
 				case 2:
 					elfrel = elf.R_390_PLT16DBL
 				case 4:
 					elfrel = elf.R_390_PLT32DBL
 				}
 			} else {
-				switch r.Siz {
+				switch siz {
 				case 4:
 					elfrel = elf.R_390_PLT32
 				case 8:
@@ -288,14 +289,14 @@
 			}
 		} else {
 			if isdbl {
-				switch r.Siz {
+				switch siz {
 				case 2:
 					elfrel = elf.R_390_PC16DBL
 				case 4:
 					elfrel = elf.R_390_PC32DBL
 				}
 			} else {
-				switch r.Siz {
+				switch siz {
 				case 2:
 					elfrel = elf.R_390_PC16
 				case 4:
@@ -363,53 +364,42 @@
 	}
 }
 
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool {
 	return false
 }
 
-func archreloc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-	if target.IsExternal() {
-		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(syms.GOT), true
-	}
-
-	return val, false
+func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (o int64, needExtReloc bool, ok bool) {
+	return val, false, false
 }
 
-func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-	switch r.Variant & sym.RV_TYPE_MASK {
+func archrelocvariant(target *ld.Target, ldr *loader.Loader, r loader.Reloc2, rv sym.RelocVariant, s loader.Sym, t int64) int64 {
+	switch rv & sym.RV_TYPE_MASK {
 	default:
-		ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
+		ldr.Errorf(s, "unexpected relocation variant %d", rv)
 		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)
+		if t&1 != 0 {
+			ldr.Errorf(s, "%s+%v is not 2-byte aligned", ldr.SymName(r.Sym()), ldr.SymValue(r.Sym()))
 		}
 		return t >> 1
 	}
 }
 
-func addpltsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
+func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
 	if ldr.SymPlt(s) >= 0 {
 		return
 	}
 
-	ld.Adddynsym2(ldr, target, syms, s)
+	ld.Adddynsym(ldr, target, syms, s)
 
 	if target.IsElf() {
-		plt := ldr.MakeSymbolUpdater(syms.PLT2)
-		got := ldr.MakeSymbolUpdater(syms.GOT2)
-		rela := ldr.MakeSymbolUpdater(syms.RelaPLT2)
+		plt := ldr.MakeSymbolUpdater(syms.PLT)
+		got := ldr.MakeSymbolUpdater(syms.GOT)
+		rela := ldr.MakeSymbolUpdater(syms.RelaPLT)
 		if plt.Size() == 0 {
 			panic("plt is not set up")
 		}
@@ -464,92 +454,3 @@
 		ldr.Errorf(s, "addpltsym: unsupported binary format")
 	}
 }
-
-func addgotsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
-	if ldr.SymGot(s) >= 0 {
-		return
-	}
-
-	ld.Adddynsym2(ldr, target, syms, s)
-	got := ldr.MakeSymbolUpdater(syms.GOT2)
-	ldr.SetGot(s, int32(got.Size()))
-	got.AddUint64(target.Arch, 0)
-
-	if target.IsElf() {
-		rela := ldr.MakeSymbolUpdater(syms.Rela2)
-		rela.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
-		rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(ldr.SymDynid(s)), uint32(elf.R_390_GLOB_DAT)))
-		rela.AddUint64(target.Arch, 0)
-	} else {
-		ldr.Errorf(s, "addgotsym: unsupported binary format")
-	}
-}
-
-func asmb(ctxt *ld.Link, _ *loader.Loader) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	var wg sync.WaitGroup
-	sect := ld.Segtext.Sections[0]
-	offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-	ld.WriteParallel(&wg, ld.Codeblk, ctxt, offset, sect.Vaddr, sect.Length)
-
-	for _, sect := range ld.Segtext.Sections[1:] {
-		offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, offset, sect.Vaddr, sect.Length)
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrodata.Fileoff, ld.Segrodata.Vaddr, ld.Segrodata.Filelen)
-	}
-
-	if ld.Segrelrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrelrodata.Fileoff, ld.Segrelrodata.Vaddr, ld.Segrelrodata.Filelen)
-	}
-
-	ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segdata.Fileoff, ld.Segdata.Vaddr, ld.Segdata.Filelen)
-
-	ld.WriteParallel(&wg, ld.Dwarfblk, ctxt, ld.Segdwarf.Fileoff, ld.Segdwarf.Vaddr, ld.Segdwarf.Filelen)
-	wg.Wait()
-}
-
-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.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))
-	}
-
-	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/link/internal/s390x/obj.go b/src/cmd/link/internal/s390x/obj.go
index d4ac5af..bb62fe1 100644
--- a/src/cmd/link/internal/s390x/obj.go
+++ b/src/cmd/link/internal/s390x/obj.go
@@ -46,15 +46,13 @@
 		Dwarfregsp: dwarfRegSP,
 		Dwarfreglr: dwarfRegLR,
 
-		Adddynrel2:       adddynrel2,
+		Adddynrel:        adddynrel,
 		Archinit:         archinit,
 		Archreloc:        archreloc,
 		Archrelocvariant: archrelocvariant,
-		Asmb:             asmb,  // in asm.go
-		Asmb2:            asmb2, // in asm.go
 		Elfreloc1:        elfreloc1,
 		Elfsetupplt:      elfsetupplt,
-		Gentext2:         gentext2,
+		Gentext:          gentext,
 		Machoreloc1:      machoreloc1,
 
 		Linuxdynld: "/lib64/ld64.so.1",
diff --git a/src/cmd/link/internal/sym/attribute.go b/src/cmd/link/internal/sym/attribute.go
deleted file mode 100644
index eda3fe6..0000000
--- a/src/cmd/link/internal/sym/attribute.go
+++ /dev/null
@@ -1,129 +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 "sync/atomic"
-
-// 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) load() Attribute { return Attribute(atomic.LoadInt32((*int32)(a))) }
-
-func (a *Attribute) DuplicateOK() bool      { return a.load()&AttrDuplicateOK != 0 }
-func (a *Attribute) External() bool         { return a.load()&AttrExternal != 0 }
-func (a *Attribute) NoSplit() bool          { return a.load()&AttrNoSplit != 0 }
-func (a *Attribute) Reachable() bool        { return a.load()&AttrReachable != 0 }
-func (a *Attribute) CgoExportDynamic() bool { return a.load()&AttrCgoExportDynamic != 0 }
-func (a *Attribute) CgoExportStatic() bool  { return a.load()&AttrCgoExportStatic != 0 }
-func (a *Attribute) Special() bool          { return a.load()&AttrSpecial != 0 }
-func (a *Attribute) StackCheck() bool       { return a.load()&AttrStackCheck != 0 }
-func (a *Attribute) NotInSymbolTable() bool { return a.load()&AttrNotInSymbolTable != 0 }
-func (a *Attribute) OnList() bool           { return a.load()&AttrOnList != 0 }
-func (a *Attribute) Local() bool            { return a.load()&AttrLocal != 0 }
-func (a *Attribute) ReflectMethod() bool    { return a.load()&AttrReflectMethod != 0 }
-func (a *Attribute) MakeTypelink() bool     { return a.load()&AttrMakeTypelink != 0 }
-func (a *Attribute) Shared() bool           { return a.load()&AttrShared != 0 }
-func (a *Attribute) VisibilityHidden() bool { return a.load()&AttrVisibilityHidden != 0 }
-func (a *Attribute) SubSymbol() bool        { return a.load()&AttrSubSymbol != 0 }
-func (a *Attribute) Container() bool        { return a.load()&AttrContainer != 0 }
-func (a *Attribute) TopFrame() bool         { return a.load()&AttrTopFrame != 0 }
-func (a *Attribute) ReadOnly() bool         { return a.load()&AttrReadOnly != 0 }
-
-func (a *Attribute) CgoExport() bool {
-	return a.CgoExportDynamic() || a.CgoExportStatic()
-}
-
-func (a *Attribute) Set(flag Attribute, value bool) {
-	// XXX it would be nice if we have atomic And, Or.
-	for {
-		a0 := a.load()
-		var anew Attribute
-		if value {
-			anew = a0 | flag
-		} else {
-			anew = a0 &^ flag
-		}
-		if atomic.CompareAndSwapInt32((*int32)(a), int32(a0), int32(anew)) {
-			return
-		}
-	}
-}
diff --git a/src/cmd/link/internal/sym/compilation_unit.go b/src/cmd/link/internal/sym/compilation_unit.go
index b8b6845..d9bfc84 100644
--- a/src/cmd/link/internal/sym/compilation_unit.go
+++ b/src/cmd/link/internal/sym/compilation_unit.go
@@ -16,18 +16,13 @@
 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
 
-	Consts2    LoaderSym   // Package constants DIEs (loader)
-	FuncDIEs2  []LoaderSym // Function DIE subtrees (loader)
-	AbsFnDIEs2 []LoaderSym // Abstract function DIE subtrees (loader)
-	RangeSyms2 []LoaderSym // Symbols for debug_range (loader)
-	Textp2     []LoaderSym // Text symbols in this CU (loader)
+	Consts    LoaderSym   // Package constants DIEs
+	FuncDIEs  []LoaderSym // Function DIE subtrees
+	AbsFnDIEs []LoaderSym // Abstract function DIE subtrees
+	RangeSyms []LoaderSym // Symbols for debug_range
+	Textp     []LoaderSym // Text symbols in this CU
 }
diff --git a/src/cmd/link/internal/sym/library.go b/src/cmd/link/internal/sym/library.go
index c9be3ab..7f6e63c 100644
--- a/src/cmd/link/internal/sym/library.go
+++ b/src/cmd/link/internal/sym/library.go
@@ -12,16 +12,14 @@
 	File        string
 	Pkg         string
 	Shlib       string
-	Hash        string
 	Fingerprint goobj2.FingerprintType
 	Autolib     []goobj2.ImportedPkg
 	Imports     []*Library
 	Main        bool
-	Safe        bool
 	Units       []*CompilationUnit
 
-	Textp2       []LoaderSym // text syms defined in this library
-	DupTextSyms2 []LoaderSym // dupok text syms defined in this library
+	Textp       []LoaderSym // text syms defined in this library
+	DupTextSyms []LoaderSym // dupok text syms defined in this library
 }
 
 func (l Library) String() string {
diff --git a/src/cmd/link/internal/sym/reloc.go b/src/cmd/link/internal/sym/reloc.go
index f589447..a543233 100644
--- a/src/cmd/link/internal/sym/reloc.go
+++ b/src/cmd/link/internal/sym/reloc.go
@@ -10,41 +10,6 @@
 	"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
 
@@ -107,22 +72,3 @@
 
 	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/link/internal/sym/segment.go b/src/cmd/link/internal/sym/segment.go
index 5aa0bc5..9b49c62 100644
--- a/src/cmd/link/internal/sym/segment.go
+++ b/src/cmd/link/internal/sym/segment.go
@@ -55,7 +55,6 @@
 	Elfsect interface{} // an *ld.ElfShdr
 	Reloff  uint64
 	Rellen  uint64
-	Sym     *Symbol   // symbol for the section, if any
-	Sym2    LoaderSym // symbol for the section, if any
+	Sym     LoaderSym // symbol for the section, if any
 	Index   uint16    // each section has a unique index, used internally
 }
diff --git a/src/cmd/link/internal/sym/sizeof_test.go b/src/cmd/link/internal/sym/sizeof_test.go
deleted file mode 100644
index f358cce..0000000
--- a/src/cmd/link/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{}, 80, 128},
-	}
-
-	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/link/internal/sym/symbol.go b/src/cmd/link/internal/sym/symbol.go
index 3c3717f..1a4165e 100644
--- a/src/cmd/link/internal/sym/symbol.go
+++ b/src/cmd/link/internal/sym/symbol.go
@@ -6,46 +6,8 @@
 
 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
-	Value   int64
-	Size    int64
-	Outer   *Symbol
-	SymIdx  LoaderSym
-	auxinfo *AuxSymbol
-	Sect    *Section
-	// 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
@@ -72,363 +34,6 @@
 	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) Len() int64 {
-	return s.Size
-}
-
-func (s *Symbol) Length(dwarfContext 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
-}
-
 type Pcdata struct {
 	P []byte
 }
diff --git a/src/cmd/link/internal/sym/symbols.go b/src/cmd/link/internal/sym/symbols.go
deleted file mode 100644
index 721828d..0000000
--- a/src/cmd/link/internal/sym/symbols.go
+++ /dev/null
@@ -1,63 +0,0 @@
-// Derived from Inferno utils/6l/l.h and related files.
-// https://bitbucket.org/inferno-os/inferno-os/src/master/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 {
-	// Symbol lookup based on name and indexed by version.
-	versions int
-
-	// Provided by the loader
-
-	// Look up the symbol with the given name and version, creating the
-	// symbol if it is not found.
-	Lookup func(name string, v int) *Symbol
-
-	// Look up the symbol with the given name and version, returning nil
-	// if it is not found.
-	ROLookup func(name string, v int) *Symbol
-}
-
-func NewSymbols() *Symbols {
-	return &Symbols{
-		versions: SymVerStatic,
-	}
-}
-
-// Allocate a new version (i.e. symbol namespace).
-func (syms *Symbols) IncVersion() int {
-	syms.versions++
-	return syms.versions - 1
-}
-
-// returns the maximum version number
-func (syms *Symbols) MaxVersion() int {
-	return syms.versions
-}
diff --git a/src/cmd/link/internal/sym/symkind.go b/src/cmd/link/internal/sym/symkind.go
index 3a1cad9..3e47d9a 100644
--- a/src/cmd/link/internal/sym/symkind.go
+++ b/src/cmd/link/internal/sym/symkind.go
@@ -102,14 +102,19 @@
 	SMACHOINDIRECTPLT
 	SMACHOINDIRECTGOT
 	SFILEPATH
-	SCONST
 	SDYNIMPORT
 	SHOSTOBJ
 	SUNDEFEXT // Undefined symbol for resolution by external linker
 
 	// Sections for debugging information
 	SDWARFSECT
-	SDWARFINFO
+	// DWARF symbol types
+	SDWARFCUINFO
+	SDWARFCONST
+	SDWARFFCN
+	SDWARFABSFCN
+	SDWARFTYPE
+	SDWARFVAR
 	SDWARFRANGE
 	SDWARFLOC
 	SDWARFLINES
@@ -129,7 +134,12 @@
 	SBSS,
 	SNOPTRBSS,
 	STLSBSS,
-	SDWARFINFO,
+	SDWARFCUINFO,
+	SDWARFCONST,
+	SDWARFFCN,
+	SDWARFABSFCN,
+	SDWARFTYPE,
+	SDWARFVAR,
 	SDWARFRANGE,
 	SDWARFLOC,
 	SDWARFLINES,
diff --git a/src/cmd/link/internal/sym/symkind_string.go b/src/cmd/link/internal/sym/symkind_string.go
index 97af992..47b2406 100644
--- a/src/cmd/link/internal/sym/symkind_string.go
+++ b/src/cmd/link/internal/sym/symkind_string.go
@@ -1,4 +1,4 @@
-// Code generated by "stringer -type=SymKind symkind.go"; DO NOT EDIT.
+// Code generated by "stringer -type=SymKindstringer -type=SymKind"; DO NOT EDIT.
 
 package sym
 
@@ -52,21 +52,25 @@
 	_ = 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]
+	_ = x[SDYNIMPORT-44]
+	_ = x[SHOSTOBJ-45]
+	_ = x[SUNDEFEXT-46]
+	_ = x[SDWARFSECT-47]
+	_ = x[SDWARFCUINFO-48]
+	_ = x[SDWARFCONST-49]
+	_ = x[SDWARFFCN-50]
+	_ = x[SDWARFABSFCN-51]
+	_ = x[SDWARFTYPE-52]
+	_ = x[SDWARFVAR-53]
+	_ = x[SDWARFRANGE-54]
+	_ = x[SDWARFLOC-55]
+	_ = x[SDWARFLINES-56]
+	_ = x[SABIALIAS-57]
 }
 
-const _SymKind_name = "SxxxSTEXTSELFRXSECTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSMACHOPLTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSFirstWritableSBUILDINFOSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASXCOFFTOCSBSSSNOPTRBSSSLIBFUZZER_EXTRA_COUNTERSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILEPATHSCONSTSDYNIMPORTSHOSTOBJSUNDEFEXTSDWARFSECTSDWARFINFOSDWARFRANGESDWARFLOCSDWARFLINESSABIALIAS"
+const _SymKind_name = "SxxxSTEXTSELFRXSECTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSMACHOPLTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSFirstWritableSBUILDINFOSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASXCOFFTOCSBSSSNOPTRBSSSLIBFUZZER_EXTRA_COUNTERSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILEPATHSDYNIMPORTSHOSTOBJSUNDEFEXTSDWARFSECTSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINESSABIALIAS"
 
-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}
+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, 426, 434, 443, 453, 465, 476, 485, 497, 507, 516, 527, 536, 547, 556}
 
 func (i SymKind) String() string {
 	if i >= SymKind(len(_SymKind_index)-1) {
diff --git a/src/cmd/link/internal/wasm/asm.go b/src/cmd/link/internal/wasm/asm.go
index 1eb3291..2be4adc 100644
--- a/src/cmd/link/internal/wasm/asm.go
+++ b/src/cmd/link/internal/wasm/asm.go
@@ -39,7 +39,7 @@
 // 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 gentext2(ctxt *ld.Link, ldr *loader.Loader) {
+func gentext(ctxt *ld.Link, ldr *loader.Loader) {
 }
 
 type wasmFunc struct {
@@ -119,7 +119,7 @@
 
 // asmb writes the final WebAssembly module binary.
 // Spec: https://webassembly.github.io/spec/core/binary/modules.html
-func asmb2(ctxt *ld.Link) {
+func asmb2(ctxt *ld.Link, ldr *loader.Loader) {
 	types := []*wasmFuncType{
 		// For normal Go functions, the single parameter is PC_B,
 		// the return value is
@@ -135,13 +135,15 @@
 			Type: lookupType(&wasmFuncType{Params: []byte{I32}}, &types),
 		},
 	}
-	hostImportMap := make(map[*sym.Symbol]int64)
+	hostImportMap := make(map[loader.Sym]int64)
 	for _, fn := range ctxt.Textp {
-		for _, r := range fn.R {
-			if r.Type == objabi.R_WASMIMPORT {
-				hostImportMap[r.Sym] = int64(len(hostImports))
+		relocs := ldr.Relocs(fn)
+		for ri := 0; ri < relocs.Count(); ri++ {
+			r := relocs.At2(ri)
+			if r.Type() == objabi.R_WASMIMPORT {
+				hostImportMap[r.Sym()] = int64(len(hostImports))
 				hostImports = append(hostImports, &wasmFunc{
-					Name: r.Sym.Name,
+					Name: ldr.SymName(r.Sym()),
 					Type: lookupType(&wasmFuncType{Params: []byte{I32}}, &types),
 				})
 			}
@@ -153,38 +155,42 @@
 	fns := make([]*wasmFunc, len(ctxt.Textp))
 	for i, fn := range ctxt.Textp {
 		wfn := new(bytes.Buffer)
-		if fn.Name == "go.buildid" {
+		if ldr.SymName(fn) == "go.buildid" {
 			writeUleb128(wfn, 0) // number of sets of locals
 			writeI32Const(wfn, 0)
 			wfn.WriteByte(0x0b) // end
-			buildid = fn.P
+			buildid = ldr.Data(fn)
 		} else {
 			// Relocations have variable length, handle them here.
+			relocs := ldr.Relocs(fn)
+			P := ldr.Data(fn)
 			off := int32(0)
-			for _, r := range fn.R {
-				wfn.Write(fn.P[off:r.Off])
-				off = r.Off
-				switch r.Type {
+			for ri := 0; ri < relocs.Count(); ri++ {
+				r := relocs.At2(ri)
+				wfn.Write(P[off:r.Off()])
+				off = r.Off()
+				rs := ldr.ResolveABIAlias(r.Sym())
+				switch r.Type() {
 				case objabi.R_ADDR:
-					writeSleb128(wfn, r.Sym.Value+r.Add)
+					writeSleb128(wfn, ldr.SymValue(rs)+r.Add())
 				case objabi.R_CALL:
-					writeSleb128(wfn, int64(len(hostImports))+r.Sym.Value>>16-funcValueOffset)
+					writeSleb128(wfn, int64(len(hostImports))+ldr.SymValue(rs)>>16-funcValueOffset)
 				case objabi.R_WASMIMPORT:
-					writeSleb128(wfn, hostImportMap[r.Sym])
+					writeSleb128(wfn, hostImportMap[rs])
 				default:
-					ld.Errorf(fn, "bad reloc type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
+					ldr.Errorf(fn, "bad reloc type %d (%s)", r.Type(), sym.RelocName(ctxt.Arch, r.Type()))
 					continue
 				}
 			}
-			wfn.Write(fn.P[off:])
+			wfn.Write(P[off:])
 		}
 
 		typ := uint32(0)
-		if sig, ok := wasmFuncTypes[fn.Name]; ok {
+		if sig, ok := wasmFuncTypes[ldr.SymName(fn)]; ok {
 			typ = lookupType(sig, &types)
 		}
 
-		name := nameRegexp.ReplaceAllString(fn.Name, "_")
+		name := nameRegexp.ReplaceAllString(ldr.SymName(fn), "_")
 		fns[i] = &wasmFunc{Name: name, Type: typ, Code: wfn.Bytes()}
 	}
 
@@ -200,9 +206,9 @@
 	writeImportSec(ctxt, hostImports)
 	writeFunctionSec(ctxt, fns)
 	writeTableSec(ctxt, fns)
-	writeMemorySec(ctxt)
+	writeMemorySec(ctxt, ldr)
 	writeGlobalSec(ctxt)
-	writeExportSec(ctxt, len(hostImports))
+	writeExportSec(ctxt, ldr, len(hostImports))
 	writeElementSec(ctxt, uint64(len(hostImports)), uint64(len(fns)))
 	writeCodeSec(ctxt, fns)
 	writeDataSec(ctxt)
@@ -311,10 +317,10 @@
 
 // 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) {
+func writeMemorySec(ctxt *ld.Link, ldr *loader.Loader) {
 	sizeOffset := writeSecHeader(ctxt, sectionMemory)
 
-	dataSection := ctxt.Syms.Lookup("runtime.data", 0).Sect
+	dataSection := ldr.SymSect(ldr.Lookup("runtime.data", 0))
 	dataEnd := dataSection.Vaddr + dataSection.Length
 	var initialSize = dataEnd + 16<<20 // 16MB, enough for runtime init without growing
 
@@ -362,13 +368,14 @@
 // 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) {
+func writeExportSec(ctxt *ld.Link, ldr *loader.Loader, 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
+		s := ldr.Lookup("wasm_export_"+name, 0)
+		idx := uint32(lenHostImports) + uint32(ldr.SymValue(s)>>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
diff --git a/src/cmd/link/internal/wasm/obj.go b/src/cmd/link/internal/wasm/obj.go
index 9fc1a6c..f8090a3 100644
--- a/src/cmd/link/internal/wasm/obj.go
+++ b/src/cmd/link/internal/wasm/obj.go
@@ -19,7 +19,7 @@
 		AssignAddress: assignAddress,
 		Asmb:          asmb,
 		Asmb2:         asmb2,
-		Gentext2:      gentext2,
+		Gentext:       gentext,
 	}
 
 	return sys.ArchWasm, theArch
diff --git a/src/cmd/link/internal/x86/asm.go b/src/cmd/link/internal/x86/asm.go
index b218ffa..6683c79 100644
--- a/src/cmd/link/internal/x86/asm.go
+++ b/src/cmd/link/internal/x86/asm.go
@@ -38,10 +38,9 @@
 	"cmd/link/internal/sym"
 	"debug/elf"
 	"log"
-	"sync"
 )
 
-func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
+func gentext(ctxt *ld.Link, ldr *loader.Loader) {
 	if ctxt.DynlinkingGo() {
 		// We need get_pc_thunk.
 	} else {
@@ -58,7 +57,7 @@
 	}
 
 	// Generate little thunks that load the PC of the next instruction into a register.
-	thunks := make([]loader.Sym, 0, 7+len(ctxt.Textp2))
+	thunks := make([]loader.Sym, 0, 7+len(ctxt.Textp))
 	for _, r := range [...]struct {
 		name string
 		num  uint8
@@ -88,7 +87,7 @@
 
 		thunks = append(thunks, thunkfunc.Sym())
 	}
-	ctxt.Textp2 = append(thunks, ctxt.Textp2...) // keep Textp2 in dependency order
+	ctxt.Textp = append(thunks, ctxt.Textp...) // keep Textp in dependency order
 
 	initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt)
 	if initfunc == nil {
@@ -116,7 +115,7 @@
 	initfunc.AddSymRef(ctxt.Arch, ldr.Lookup("__x86.get_pc_thunk.cx", 0), 0, objabi.R_CALL, 4)
 
 	o(0x8d, 0x81)
-	initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata2, 6)
+	initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata, 6)
 
 	o(0x8d, 0x99)
 	gotsym := ldr.LookupOrCreateSym("_GLOBAL_OFFSET_TABLE_", 0)
@@ -129,7 +128,7 @@
 	o(0xc3)
 }
 
-func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
+func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
 	targ := r.Sym()
 	var targType sym.SymKind
 	if targ != 0 {
@@ -163,8 +162,8 @@
 		su.SetRelocType(rIdx, objabi.R_PCREL)
 		su.SetRelocAdd(rIdx, r.Add()+4)
 		if targType == sym.SDYNIMPORT {
-			addpltsym2(target, ldr, syms, targ)
-			su.SetRelocSym(rIdx, syms.PLT2)
+			addpltsym(target, ldr, syms, targ)
+			su.SetRelocSym(rIdx, syms.PLT)
 			su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymPlt(targ)))
 		}
 
@@ -202,7 +201,7 @@
 			return false
 		}
 
-		addgotsym2(target, ldr, syms, targ)
+		ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_386_GLOB_DAT))
 		su.SetRelocType(rIdx, objabi.R_CONST) // write r->add during relocsym
 		su.SetRelocSym(rIdx, 0)
 		su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
@@ -216,7 +215,7 @@
 	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_GOTPC):
 		su := ldr.MakeSymbolUpdater(s)
 		su.SetRelocType(rIdx, objabi.R_PCREL)
-		su.SetRelocSym(rIdx, syms.GOT2)
+		su.SetRelocSym(rIdx, syms.GOT)
 		su.SetRelocAdd(rIdx, r.Add()+4)
 		return true
 
@@ -239,8 +238,8 @@
 	case objabi.MachoRelocOffset + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 1:
 		su := ldr.MakeSymbolUpdater(s)
 		if targType == sym.SDYNIMPORT {
-			addpltsym2(target, ldr, syms, targ)
-			su.SetRelocSym(rIdx, syms.PLT2)
+			addpltsym(target, ldr, syms, targ)
+			su.SetRelocSym(rIdx, syms.PLT)
 			su.SetRelocAdd(rIdx, int64(ldr.SymPlt(targ)))
 			su.SetRelocType(rIdx, objabi.R_PCREL)
 			return true
@@ -267,8 +266,8 @@
 			return true
 		}
 
-		addgotsym2(target, ldr, syms, targ)
-		su.SetRelocSym(rIdx, syms.GOT2)
+		ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_386_GLOB_DAT))
+		su.SetRelocSym(rIdx, syms.GOT)
 		su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
 		su.SetRelocType(rIdx, objabi.R_PCREL)
 		return true
@@ -290,9 +289,9 @@
 			// External linker will do this relocation.
 			return true
 		}
-		addpltsym2(target, ldr, syms, targ)
+		addpltsym(target, ldr, syms, targ)
 		su := ldr.MakeSymbolUpdater(s)
-		su.SetRelocSym(rIdx, syms.PLT2)
+		su.SetRelocSym(rIdx, syms.PLT)
 		su.SetRelocAdd(rIdx, int64(ldr.SymPlt(targ)))
 		return true
 
@@ -301,8 +300,8 @@
 			break
 		}
 		if target.IsElf() {
-			ld.Adddynsym2(ldr, target, syms, targ)
-			rel := ldr.MakeSymbolUpdater(syms.Rel2)
+			ld.Adddynsym(ldr, target, syms, targ)
+			rel := ldr.MakeSymbolUpdater(syms.Rel)
 			rel.AddAddrPlus(target.Arch, s, int64(r.Off()))
 			rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(ldr.SymDynid(targ)), uint32(elf.R_386_32)))
 			su := ldr.MakeSymbolUpdater(s)
@@ -310,53 +309,29 @@
 			su.SetRelocSym(rIdx, 0)
 			return true
 		}
-
-		if target.IsDarwin() && ldr.SymSize(s) == int64(target.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.Adddynsym2(ldr, target, syms, targ)
-
-			got := ldr.MakeSymbolUpdater(syms.GOT2)
-			su := ldr.MakeSymbolUpdater(s)
-			su.SetType(got.Type())
-			got.PrependSub(s)
-			su.SetValue(got.Size())
-			got.AddUint32(target.Arch, 0)
-			leg := ldr.MakeSymbolUpdater(syms.LinkEditGOT2)
-			leg.AddUint32(target.Arch, uint32(ldr.SymDynid(targ)))
-			su.SetRelocType(rIdx, objabi.ElfRelocOffset) // ignore during relocsym
-			return true
-		}
 	}
 
 	return false
 }
 
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
+func elfreloc1(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
 	ctxt.Out.Write32(uint32(sectoff))
 
 	elfsym := ld.ElfSymForReloc(ctxt, r.Xsym)
-	switch r.Type {
+	siz := r.Siz()
+	switch r.Type() {
 	default:
 		return false
 	case objabi.R_ADDR, objabi.R_DWARFSECREF:
-		if r.Siz == 4 {
+		if siz == 4 {
 			ctxt.Out.Write32(uint32(elf.R_386_32) | uint32(elfsym)<<8)
 		} else {
 			return false
 		}
 	case objabi.R_GOTPCREL:
-		if r.Siz == 4 {
+		if siz == 4 {
 			ctxt.Out.Write32(uint32(elf.R_386_GOTPC))
-			if r.Xsym.Name != "_GLOBAL_OFFSET_TABLE_" {
+			if ldr.SymName(r.Xsym) != "_GLOBAL_OFFSET_TABLE_" {
 				ctxt.Out.Write32(uint32(sectoff))
 				ctxt.Out.Write32(uint32(elf.R_386_GOT32) | uint32(elfsym)<<8)
 			}
@@ -364,8 +339,8 @@
 			return false
 		}
 	case objabi.R_CALL:
-		if r.Siz == 4 {
-			if r.Xsym.Type == sym.SDYNIMPORT {
+		if siz == 4 {
+			if ldr.SymType(r.Xsym) == 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)
@@ -374,19 +349,19 @@
 			return false
 		}
 	case objabi.R_PCREL:
-		if r.Siz == 4 {
+		if 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 {
+		if 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 {
+		if 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)
@@ -398,24 +373,25 @@
 	return true
 }
 
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool {
 	return false
 }
 
-func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+func pereloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
 	var v uint32
 
 	rs := r.Xsym
+	rt := r.Type()
 
-	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)
+	if ldr.SymDynid(rs) < 0 {
+		ldr.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs))
 		return false
 	}
 
 	out.Write32(uint32(sectoff))
-	out.Write32(uint32(rs.Dynid))
+	out.Write32(uint32(ldr.SymDynid(rs)))
 
-	switch r.Type {
+	switch rt {
 	default:
 		return false
 
@@ -435,13 +411,13 @@
 	return true
 }
 
-func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, sym loader.Sym, val int64) (int64, bool, bool) {
-	return val, false, false
+func archreloc(*ld.Target, *loader.Loader, *ld.ArchSyms, loader.Reloc2, *loader.ExtReloc, loader.Sym, int64) (int64, bool, bool) {
+	return -1, false, false
 }
 
-func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
+func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc2, sym.RelocVariant, loader.Sym, int64) int64 {
 	log.Fatalf("unexpected relocation variant")
-	return t
+	return -1
 }
 
 func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
@@ -469,17 +445,17 @@
 	}
 }
 
-func addpltsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
+func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
 	if ldr.SymPlt(s) >= 0 {
 		return
 	}
 
-	ld.Adddynsym2(ldr, target, syms, s)
+	ld.Adddynsym(ldr, target, syms, s)
 
 	if target.IsElf() {
-		plt := ldr.MakeSymbolUpdater(syms.PLT2)
-		got := ldr.MakeSymbolUpdater(syms.GOTPLT2)
-		rel := ldr.MakeSymbolUpdater(syms.RelPLT2)
+		plt := ldr.MakeSymbolUpdater(syms.PLT)
+		got := ldr.MakeSymbolUpdater(syms.GOTPLT)
+		rel := ldr.MakeSymbolUpdater(syms.RelPLT)
 		if plt.Size() == 0 {
 			panic("plt is not set up")
 		}
@@ -510,168 +486,7 @@
 		rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(sDynid), uint32(elf.R_386_JMP_SLOT)))
 
 		ldr.SetPlt(s, int32(plt.Size()-16))
-	} else if target.IsDarwin() {
-		// Same laziness as in 6l.
-
-		plt := ldr.MakeSymbolUpdater(syms.PLT2)
-
-		addgotsym2(target, ldr, syms, s)
-
-		sDynid := ldr.SymDynid(s)
-		lep := ldr.MakeSymbolUpdater(syms.LinkEditPLT2)
-		lep.AddUint32(target.Arch, uint32(sDynid))
-
-		// jmpq *got+size(IP)
-		ldr.SetPlt(s, int32(plt.Size()))
-
-		plt.AddUint8(0xff)
-		plt.AddUint8(0x25)
-		plt.AddAddrPlus(target.Arch, syms.GOT2, int64(ldr.SymGot(s)))
 	} else {
 		ldr.Errorf(s, "addpltsym: unsupported binary format")
 	}
 }
-
-func addgotsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
-	if ldr.SymGot(s) >= 0 {
-		return
-	}
-
-	ld.Adddynsym2(ldr, target, syms, s)
-	got := ldr.MakeSymbolUpdater(syms.GOT2)
-	ldr.SetGot(s, int32(got.Size()))
-	got.AddUint32(target.Arch, 0)
-
-	if target.IsElf() {
-		rel := ldr.MakeSymbolUpdater(syms.Rel2)
-		rel.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
-		rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(ldr.SymDynid(s)), uint32(elf.R_386_GLOB_DAT)))
-	} else if target.IsDarwin() {
-		leg := ldr.MakeSymbolUpdater(syms.LinkEditGOT2)
-		leg.AddUint32(target.Arch, uint32(ldr.SymDynid(s)))
-	} else {
-		ldr.Errorf(s, "addgotsym: unsupported binary format")
-	}
-}
-
-func asmb(ctxt *ld.Link, _ *loader.Loader) {
-	if ctxt.IsELF {
-		ld.Asmbelfsetup()
-	}
-
-	var wg sync.WaitGroup
-	sect := ld.Segtext.Sections[0]
-	offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-	f := func(ctxt *ld.Link, out *ld.OutBuf, start, length int64) {
-		ld.CodeblkPad(ctxt, out, start, length, []byte{0xCC})
-	}
-	ld.WriteParallel(&wg, f, ctxt, offset, sect.Vaddr, sect.Length)
-
-	for _, sect := range ld.Segtext.Sections[1:] {
-		offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, offset, sect.Vaddr, sect.Length)
-	}
-
-	if ld.Segrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrodata.Fileoff, ld.Segrodata.Vaddr, ld.Segrodata.Filelen)
-	}
-
-	if ld.Segrelrodata.Filelen > 0 {
-		ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrelrodata.Fileoff, ld.Segrelrodata.Vaddr, ld.Segrelrodata.Filelen)
-	}
-
-	ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segdata.Fileoff, ld.Segdata.Vaddr, ld.Segdata.Filelen)
-
-	ld.WriteParallel(&wg, ld.Dwarfblk, ctxt, ld.Segdwarf.Fileoff, ld.Segdwarf.Vaddr, ld.Segdwarf.Filelen)
-	wg.Wait()
-}
-
-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.Write(ld.Elfstrdat)
-
-				if ctxt.LinkMode == ld.LinkExternal {
-					ld.Elfemitreloc(ctxt)
-				}
-			}
-
-		case objabi.Hplan9:
-			ld.Asmplan9sym(ctxt)
-
-			sym := ctxt.Syms.Lookup("pclntab", 0)
-			if sym != nil {
-				ld.Lcsize = int32(len(sym.P))
-				ctxt.Out.Write(sym.P)
-			}
-
-		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)
-	}
-}
diff --git a/src/cmd/link/internal/x86/obj.go b/src/cmd/link/internal/x86/obj.go
index cd33f44..e1c469c 100644
--- a/src/cmd/link/internal/x86/obj.go
+++ b/src/cmd/link/internal/x86/obj.go
@@ -45,16 +45,18 @@
 		Minalign:   minAlign,
 		Dwarfregsp: dwarfRegSP,
 		Dwarfreglr: dwarfRegLR,
+		// 0xCC is INT $3 - breakpoint instruction
+		CodePad: []byte{0xCC},
 
-		Adddynrel2:       adddynrel2,
+		Plan9Magic: uint32(4*11*11 + 7),
+
+		Adddynrel:        adddynrel,
 		Archinit:         archinit,
-		Archreloc2:       archreloc2,
+		Archreloc:        archreloc,
 		Archrelocvariant: archrelocvariant,
-		Asmb:             asmb,
-		Asmb2:            asmb2,
 		Elfreloc1:        elfreloc1,
 		Elfsetupplt:      elfsetupplt,
-		Gentext2:         gentext2,
+		Gentext:          gentext,
 		Machoreloc1:      machoreloc1,
 		PEreloc1:         pereloc1,
 
diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go
index 5ff9912..635c55d 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/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 13baf3e..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/master/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 a9afb3a..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/master/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 ab85ab2..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/master/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 9dc4ca0..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/master/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 d16dc27..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/master/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/master/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 397990f..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/master/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 4f29fbe..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/master/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 4aa2708..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/master/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 b5be5ec..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/master/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 453e12b..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/master/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 02230cb..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/master/utils/6l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/master/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 844580b..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/master/utils/6l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/master/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 cc42901..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/master/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/master/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 514abee..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/master/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 fdbb1de..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/master/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 d5b3a5e..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/master/utils/6l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/master/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 86c3c22b..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/master/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 371c1ea..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/master/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 affc48c..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/master/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 a59bc21..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/master/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 7dcf805..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/master/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 837af0e..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/master/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 25a5153..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/master/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 6b57abf..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/master/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 e8d3b68..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/master/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 f508fbd..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/master/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 23cda2a..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/master/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 f040587..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/master/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 7317cdc..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/master/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 395679a..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/master/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 9dd0620..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/master/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 3a1cad9..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/master/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 df8a236..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/master/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 5875d45..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/master/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 c9ec0bf..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/master/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)
-}
