]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd: delete old object support
authorCherry Zhang <cherryyz@google.com>
Fri, 1 May 2020 23:13:30 +0000 (19:13 -0400)
committerCherry Zhang <cherryyz@google.com>
Mon, 4 May 2020 17:00:27 +0000 (17:00 +0000)
We are not going to merge to master until Go 1.16 cycle. The old
object support can go now.

Change-Id: I93e6f584974c7749d0a0c2e7a96def35134dc566
Reviewed-on: https://go-review.googlesource.com/c/go/+/231918
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
102 files changed:
src/cmd/asm/internal/flags/flags.go
src/cmd/asm/main.go
src/cmd/compile/internal/gc/iexport.go
src/cmd/compile/internal/gc/iimport.go
src/cmd/compile/internal/gc/main.go
src/cmd/internal/dwarf/dwarf.go
src/cmd/internal/goobj/goobj_test.go
src/cmd/internal/obj/link.go
src/cmd/internal/obj/objfile.go
src/cmd/internal/obj/objfile2.go
src/cmd/internal/obj/plist.go
src/cmd/internal/obj/sym.go
src/cmd/link/internal/ld/main.go
src/cmd/link/internal/loader/loader.go
src/cmd/link/link_test.go
src/cmd/nm/nm_test.go
src/cmd/objdump/objdump_test.go
src/cmd/oldlink/doc.go [deleted file]
src/cmd/oldlink/internal/amd64/asm.go [deleted file]
src/cmd/oldlink/internal/amd64/l.go [deleted file]
src/cmd/oldlink/internal/amd64/obj.go [deleted file]
src/cmd/oldlink/internal/arm/asm.go [deleted file]
src/cmd/oldlink/internal/arm/l.go [deleted file]
src/cmd/oldlink/internal/arm/obj.go [deleted file]
src/cmd/oldlink/internal/arm64/asm.go [deleted file]
src/cmd/oldlink/internal/arm64/l.go [deleted file]
src/cmd/oldlink/internal/arm64/obj.go [deleted file]
src/cmd/oldlink/internal/ld/ar.go [deleted file]
src/cmd/oldlink/internal/ld/config.go [deleted file]
src/cmd/oldlink/internal/ld/data.go [deleted file]
src/cmd/oldlink/internal/ld/deadcode.go [deleted file]
src/cmd/oldlink/internal/ld/deadcode2.go [deleted file]
src/cmd/oldlink/internal/ld/decodesym.go [deleted file]
src/cmd/oldlink/internal/ld/dwarf.go [deleted file]
src/cmd/oldlink/internal/ld/elf.go [deleted file]
src/cmd/oldlink/internal/ld/execarchive.go [deleted file]
src/cmd/oldlink/internal/ld/execarchive_noexec.go [deleted file]
src/cmd/oldlink/internal/ld/go.go [deleted file]
src/cmd/oldlink/internal/ld/ld.go [deleted file]
src/cmd/oldlink/internal/ld/lib.go [deleted file]
src/cmd/oldlink/internal/ld/link.go [deleted file]
src/cmd/oldlink/internal/ld/macho.go [deleted file]
src/cmd/oldlink/internal/ld/macho_combine_dwarf.go [deleted file]
src/cmd/oldlink/internal/ld/main.go [deleted file]
src/cmd/oldlink/internal/ld/outbuf.go [deleted file]
src/cmd/oldlink/internal/ld/outbuf_mmap.go [deleted file]
src/cmd/oldlink/internal/ld/outbuf_nommap.go [deleted file]
src/cmd/oldlink/internal/ld/outbuf_windows.go [deleted file]
src/cmd/oldlink/internal/ld/pcln.go [deleted file]
src/cmd/oldlink/internal/ld/pe.go [deleted file]
src/cmd/oldlink/internal/ld/sym.go [deleted file]
src/cmd/oldlink/internal/ld/symtab.go [deleted file]
src/cmd/oldlink/internal/ld/testdata/httptest/main/main.go [deleted file]
src/cmd/oldlink/internal/ld/testdata/issue10978/main.go [deleted file]
src/cmd/oldlink/internal/ld/testdata/issue10978/main.s [deleted file]
src/cmd/oldlink/internal/ld/testdata/issue25459/a/a.go [deleted file]
src/cmd/oldlink/internal/ld/testdata/issue25459/main/main.go [deleted file]
src/cmd/oldlink/internal/ld/testdata/issue26237/b.dir/b.go [deleted file]
src/cmd/oldlink/internal/ld/testdata/issue26237/main/main.go [deleted file]
src/cmd/oldlink/internal/ld/testdata/issue32233/lib/ObjC.m [deleted file]
src/cmd/oldlink/internal/ld/testdata/issue32233/lib/lib.go [deleted file]
src/cmd/oldlink/internal/ld/testdata/issue32233/main/main.go [deleted file]
src/cmd/oldlink/internal/ld/typelink.go [deleted file]
src/cmd/oldlink/internal/ld/util.go [deleted file]
src/cmd/oldlink/internal/ld/xcoff.go [deleted file]
src/cmd/oldlink/internal/loadelf/ldelf.go [deleted file]
src/cmd/oldlink/internal/loader/loader.go [deleted file]
src/cmd/oldlink/internal/loadmacho/ldmacho.go [deleted file]
src/cmd/oldlink/internal/loadpe/ldpe.go [deleted file]
src/cmd/oldlink/internal/loadxcoff/ldxcoff.go [deleted file]
src/cmd/oldlink/internal/mips/asm.go [deleted file]
src/cmd/oldlink/internal/mips/l.go [deleted file]
src/cmd/oldlink/internal/mips/obj.go [deleted file]
src/cmd/oldlink/internal/mips64/asm.go [deleted file]
src/cmd/oldlink/internal/mips64/l.go [deleted file]
src/cmd/oldlink/internal/mips64/obj.go [deleted file]
src/cmd/oldlink/internal/objfile/objfile.go [deleted file]
src/cmd/oldlink/internal/ppc64/asm.go [deleted file]
src/cmd/oldlink/internal/ppc64/l.go [deleted file]
src/cmd/oldlink/internal/ppc64/obj.go [deleted file]
src/cmd/oldlink/internal/riscv64/asm.go [deleted file]
src/cmd/oldlink/internal/riscv64/l.go [deleted file]
src/cmd/oldlink/internal/riscv64/obj.go [deleted file]
src/cmd/oldlink/internal/s390x/asm.go [deleted file]
src/cmd/oldlink/internal/s390x/l.go [deleted file]
src/cmd/oldlink/internal/s390x/obj.go [deleted file]
src/cmd/oldlink/internal/sym/attribute.go [deleted file]
src/cmd/oldlink/internal/sym/compilation_unit.go [deleted file]
src/cmd/oldlink/internal/sym/library.go [deleted file]
src/cmd/oldlink/internal/sym/reloc.go [deleted file]
src/cmd/oldlink/internal/sym/segment.go [deleted file]
src/cmd/oldlink/internal/sym/sizeof_test.go [deleted file]
src/cmd/oldlink/internal/sym/symbol.go [deleted file]
src/cmd/oldlink/internal/sym/symbols.go [deleted file]
src/cmd/oldlink/internal/sym/symkind.go [deleted file]
src/cmd/oldlink/internal/sym/symkind_string.go [deleted file]
src/cmd/oldlink/internal/wasm/asm.go [deleted file]
src/cmd/oldlink/internal/wasm/obj.go [deleted file]
src/cmd/oldlink/internal/x86/asm.go [deleted file]
src/cmd/oldlink/internal/x86/l.go [deleted file]
src/cmd/oldlink/internal/x86/obj.go [deleted file]
src/cmd/oldlink/main.go [deleted file]

index e8535ae9ac9d92497ba4b9d6377204d1d32398f6..1df9df9563e9767f67446da4f2a648e4e4be3d20 100644 (file)
@@ -25,8 +25,6 @@ var (
        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 (
index 9ca9797a45f4d4ca8b7406c286599922505aab90..71ee04128cbfc64b347c426c2ab12ac91a809224 100644 (file)
@@ -40,7 +40,6 @@ func main() {
        }
        ctxt.Flag_dynlink = *flags.Dynlink
        ctxt.Flag_shared = *flags.Shared || *flags.Dynlink
-       ctxt.Flag_go115newobj = *flags.Go115Newobj
        ctxt.IsAsm = true
        switch *flags.Spectre {
        default:
index 35b8d985cb3ef39448dc8589b144eb8805dc165f..32cc50fda1f2fba19ba4fdb31979b06fa83410be 100644 (file)
@@ -997,18 +997,16 @@ func (w *exportWriter) linkname(s *types.Sym) {
 }
 
 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))
        }
 }
 
index f3e65ff7365faf7c23fb8bdad74f482d49fc3f47..7c0764c677e902bb4e4743bfd0a664fa107ba10b 100644 (file)
@@ -696,16 +696,14 @@ func (r *importReader) linkname(s *types.Sym) {
 }
 
 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)
        }
 }
 
index 756cdbd3c9bcbb9e01c8a64f90fd46e1448699e0..ba40582f4f0c2d7c5cd364d15c15c892af849a6e 100644 (file)
@@ -281,7 +281,6 @@ func Main(archInit func(*Arch)) {
        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 @@ func Main(archInit func(*Arch)) {
        // 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
index db013999da75abf9db71a5f98fb2cd2f3dd1b121..6ab83639acef3cd8e49117e6c8cfc6edc34f20e4 100644 (file)
@@ -18,21 +18,9 @@ import (
        "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."
index 9f827c6a32dd12802f237e1765916486c10e4681..4acd30edc6a14b9750c189569f4a7c6d65eb2b69 100644 (file)
@@ -151,12 +151,9 @@ func buildGoobj() error {
        return nil
 }
 
-// Check that a symbol has a given name, accepting both
-// new and old objects.
-// TODO(go115newobj): remove.
+// Check that a symbol has a given name.
 func matchSymName(symname, want string) bool {
-       return symname == want ||
-               strings.HasPrefix(symname, want+"#") // new style, with index
+       return strings.HasPrefix(symname, want+"#") // new style, with index
 }
 
 func TestParseGoobj(t *testing.T) {
index 32906a3e05ab5595e2093e0e931c5124453bb16c..1b54df2c26d36ccbab4f5c7ba7c7931dc6494a80 100644 (file)
@@ -656,7 +656,6 @@ type Link struct {
        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
index 6d7f42ed0b069902370e6ab75038fccaef0411f6..6701b9bfba81c0109f5a4aa994d3ea5061f0c216 100644 (file)
 // 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 (ctxt *Link) writeSymDebugNamed(s *LSym, name string) {
        }
 }
 
-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) AddDWARFAddrSectionOffset(s dwarf.Sym, t interface{}, ofs int64)
 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 @@ func (ctxt *Link) dwarfSym(s *LSym) (dwarfInfoSym, dwarfLocSym, dwarfRangesSym,
                ctxt.Diag("dwarfSym of non-TEXT %v", s)
        }
        if s.Func.dwarfInfoSym == nil {
-               if ctxt.Flag_go115newobj {
-                       s.Func.dwarfInfoSym = &LSym{
-                               Type: objabi.SDWARFINFO,
-                       }
-                       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.dwarfInfoSym = &LSym{
+                       Type: objabi.SDWARFINFO,
+               }
+               if ctxt.Flag_locationlists {
+                       s.Func.dwarfLocSym = &LSym{
+                               Type: objabi.SDWARFLOC,
                        }
-                       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)
index 061e43c434fc6b56a770743f926753b9eeb54d25..0b3b2be41b9de652be9210a922703b657b31e279 100644 (file)
@@ -17,7 +17,7 @@ import (
 )
 
 // 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)
 
index 44ec4602decf107684ec9d4e78caceb89ca25c4f..c82257c9e94df9f6f5c038efc57c550109ce2a50 100644 (file)
@@ -139,26 +139,7 @@ func (ctxt *Link) InitTextSym(s *LSym, flag int) {
        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) {
index 4a8b0ebb6faf51788e455a50429f76c55f506abd..61ef6ff2ce796de9e5c9d538fe3e18146863c5ba 100644 (file)
@@ -165,10 +165,6 @@ func (ctxt *Link) Int64Sym(i int64) *LSym {
 // asm is set to true if this is called by the assembler (i.e. not the compiler),
 // in which case all the symbols are non-package (for now).
 func (ctxt *Link) NumberSyms(asm bool) {
-       if !ctxt.Flag_go115newobj {
-               return
-       }
-
        if ctxt.Headtype == objabi.Haix {
                // Data must be sorted to keep a constant order in TOC symbols.
                // As they are created during Progedit, two symbols can be switched between
index 1ed8ccb828a0abe4c1dfe600f5ecdacaceb8619e..b95bab3d898d4251fda625cb87159e7e84aeb78c 100644 (file)
@@ -39,7 +39,6 @@ import (
        "flag"
        "log"
        "os"
-       "os/exec"
        "runtime"
        "runtime/pprof"
        "strings"
@@ -99,8 +98,6 @@ var (
 
        benchmarkFlag     = flag.String("benchmark", "", "set to 'mem' or 'cpu' to enable phase benchmarking")
        benchmarkFileFlag = flag.String("benchmarkprofile", "", "emit phase profiles to `base`_phase.{cpu,mem}prof")
-
-       flagGo115Newobj = flag.Bool("go115newobj", true, "use new object file format")
 )
 
 // Main is the main entry point for the linker code.
@@ -140,10 +137,6 @@ func Main(arch *sys.Arch, theArch Arch) {
 
        objabi.Flagparse(usage)
 
-       if !*flagGo115Newobj {
-               oldlink()
-       }
-
        switch *flagHeadType {
        case "":
        case "windowsgui":
@@ -415,48 +408,3 @@ func startProfile() {
                })
        }
 }
-
-// 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)
-}
index 1b62d05197a63223496b0ee95bc57f0c67cd4a30..02cd0b89d825e828c4eeeb05306d04f3f44f9431 100644 (file)
@@ -1914,7 +1914,7 @@ func (l *Loader) Preload(syms *sym.Symbols, f *bio.Reader, lib *sym.Library, uni
        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")
        }
index 1c9e1779116a6706a6cdc6facf0118b38ef41984..145eb3c4ae92db039d7f991d8e69e3b0c793aaf3 100644 (file)
@@ -535,30 +535,6 @@ func TestStrictDup(t *testing.T) {
        }
 }
 
-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 (
index a49423b21255ddce21287690820c48223c8e5cb1..cdffb68067890602a14bafd4b072b323ce6d4672 100644 (file)
@@ -335,11 +335,11 @@ func TestGoLib(t *testing.T) {
 }
 
 // Check that a symbol has a given name, accepting both
-// new and old objects.
-// TODO(go115newobj): remove.
+// with (for packaged symbols) and without index (for
+// non-package symbols).
 func matchSymName(symname, want string) bool {
        return symname == want ||
-               strings.HasPrefix(symname, want+"#") // new style, with index
+               strings.HasPrefix(symname, want+"#")
 }
 
 const testexec = `
index 814cbf45643023025d2ee57259e9bdaf3a6c25fb..be271e4fa61e7bc2c46d6f99df4c30ba9b04cead 100644 (file)
@@ -286,9 +286,8 @@ func TestDisasmGoobj(t *testing.T) {
                t.Fatalf("go tool compile fmthello.go: %v\n%s", err, out)
        }
 
-       // TODO(go115newobj): drop old object file support.
        need := []string{
-               `main(#\d+)?\(SB\)`, // either new or old object file
+               `main#\d+\(SB\)`,
                `fmthello\.go:6`,
        }
 
diff --git a/src/cmd/oldlink/doc.go b/src/cmd/oldlink/doc.go
deleted file mode 100644 (file)
index 219499b..0000000
+++ /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 (file)
index c120e4e..0000000
+++ /dev/null
@@ -1,874 +0,0 @@
-// Inferno utils/6l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package amd64
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/ld"
-       "cmd/oldlink/internal/sym"
-       "debug/elf"
-       "log"
-)
-
-func PADDR(x uint32) uint32 {
-       return x &^ 0x80000000
-}
-
-func Addcall(ctxt *ld.Link, s *sym.Symbol, t *sym.Symbol) int64 {
-       s.Attr |= sym.AttrReachable
-       i := s.Size
-       s.Size += 4
-       s.Grow(s.Size)
-       r := s.AddRel()
-       r.Sym = t
-       r.Off = int32(i)
-       r.Type = objabi.R_CALL
-       r.Siz = 4
-       return i + int64(r.Siz)
-}
-
-func gentext(ctxt *ld.Link) {
-       if !ctxt.DynlinkingGo() {
-               return
-       }
-       addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-       if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
-               // we're linking a module containing the runtime -> no need for
-               // an init function
-               return
-       }
-       addmoduledata.Attr |= sym.AttrReachable
-       initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-       initfunc.Type = sym.STEXT
-       initfunc.Attr |= sym.AttrLocal
-       initfunc.Attr |= sym.AttrReachable
-       o := func(op ...uint8) {
-               for _, op1 := range op {
-                       initfunc.AddUint8(op1)
-               }
-       }
-       // 0000000000000000 <local.dso_init>:
-       //    0:        48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # 7 <local.dso_init+0x7>
-       //                      3: R_X86_64_PC32        runtime.firstmoduledata-0x4
-       o(0x48, 0x8d, 0x3d)
-       initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata, 0)
-       //    7:        e8 00 00 00 00          callq  c <local.dso_init+0xc>
-       //                      8: R_X86_64_PLT32       runtime.addmoduledata-0x4
-       o(0xe8)
-       Addcall(ctxt, initfunc, addmoduledata)
-       //    c:        c3                      retq
-       o(0xc3)
-       if ctxt.BuildMode == ld.BuildModePlugin {
-               ctxt.Textp = append(ctxt.Textp, addmoduledata)
-       }
-       ctxt.Textp = append(ctxt.Textp, initfunc)
-       initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-       initarray_entry.Attr |= sym.AttrReachable
-       initarray_entry.Attr |= sym.AttrLocal
-       initarray_entry.Type = sym.SINITARR
-       initarray_entry.AddAddr(ctxt.Arch, initfunc)
-}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-       targ := r.Sym
-
-       switch r.Type {
-       default:
-               if r.Type >= objabi.ElfRelocOffset {
-                       ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
-                       return false
-               }
-
-               // Handle relocations found in ELF object files.
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_PC32):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected R_X86_64_PC32 relocation for dynamic symbol %s", targ.Name)
-               }
-               // TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
-               // sense and should be removed when someone has thought about it properly.
-               if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
-                       ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
-               }
-               r.Type = objabi.R_PCREL
-               r.Add += 4
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_PC64):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected R_X86_64_PC64 relocation for dynamic symbol %s", targ.Name)
-               }
-               if targ.Type == 0 || targ.Type == sym.SXREF {
-                       ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
-               }
-               r.Type = objabi.R_PCREL
-               r.Add += 8
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_PLT32):
-               r.Type = objabi.R_PCREL
-               r.Add += 4
-               if targ.Type == sym.SDYNIMPORT {
-                       addpltsym(ctxt, targ)
-                       r.Sym = ctxt.Syms.Lookup(".plt", 0)
-                       r.Add += int64(targ.Plt())
-               }
-
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_GOTPCREL),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_GOTPCRELX),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_REX_GOTPCRELX):
-               if targ.Type != sym.SDYNIMPORT {
-                       // have symbol
-                       if r.Off >= 2 && s.P[r.Off-2] == 0x8b {
-                               // turn MOVQ of GOT entry into LEAQ of symbol itself
-                               s.P[r.Off-2] = 0x8d
-
-                               r.Type = objabi.R_PCREL
-                               r.Add += 4
-                               return true
-                       }
-               }
-
-               // fall back to using GOT and hope for the best (CMOV*)
-               // TODO: just needs relocation, no need to put in .dynsym
-               addgotsym(ctxt, targ)
-
-               r.Type = objabi.R_PCREL
-               r.Sym = ctxt.Syms.Lookup(".got", 0)
-               r.Add += 4
-               r.Add += int64(targ.Got())
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_64):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected R_X86_64_64 relocation for dynamic symbol %s", targ.Name)
-               }
-               r.Type = objabi.R_ADDR
-               if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal {
-                       // For internal linking PIE, this R_ADDR relocation cannot
-                       // be resolved statically. We need to generate a dynamic
-                       // relocation. Let the code below handle it.
-                       break
-               }
-               return true
-
-       // Handle relocations found in Mach-O object files.
-       case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_UNSIGNED*2 + 0,
-               objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED*2 + 0,
-               objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_BRANCH*2 + 0:
-               // TODO: What is the difference between all these?
-               r.Type = objabi.R_ADDR
-
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected reloc for dynamic symbol %s", targ.Name)
-               }
-               return true
-
-       case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_BRANCH*2 + 1:
-               if targ.Type == sym.SDYNIMPORT {
-                       addpltsym(ctxt, targ)
-                       r.Sym = ctxt.Syms.Lookup(".plt", 0)
-                       r.Add = int64(targ.Plt())
-                       r.Type = objabi.R_PCREL
-                       return true
-               }
-               fallthrough
-
-       case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_UNSIGNED*2 + 1,
-               objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED*2 + 1,
-               objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED_1*2 + 1,
-               objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED_2*2 + 1,
-               objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED_4*2 + 1:
-               r.Type = objabi.R_PCREL
-
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected pc-relative reloc for dynamic symbol %s", targ.Name)
-               }
-               return true
-
-       case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_GOT_LOAD*2 + 1:
-               if targ.Type != sym.SDYNIMPORT {
-                       // have symbol
-                       // turn MOVQ of GOT entry into LEAQ of symbol itself
-                       if r.Off < 2 || s.P[r.Off-2] != 0x8b {
-                               ld.Errorf(s, "unexpected GOT_LOAD reloc for non-dynamic symbol %s", targ.Name)
-                               return false
-                       }
-
-                       s.P[r.Off-2] = 0x8d
-                       r.Type = objabi.R_PCREL
-                       return true
-               }
-               fallthrough
-
-       case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_GOT*2 + 1:
-               if targ.Type != sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
-               }
-               addgotsym(ctxt, targ)
-               r.Type = objabi.R_PCREL
-               r.Sym = ctxt.Syms.Lookup(".got", 0)
-               r.Add += int64(targ.Got())
-               return true
-       }
-
-       switch r.Type {
-       case objabi.R_CALL,
-               objabi.R_PCREL:
-               if targ.Type != sym.SDYNIMPORT {
-                       // nothing to do, the relocation will be laid out in reloc
-                       return true
-               }
-               if ctxt.LinkMode == ld.LinkExternal {
-                       // External linker will do this relocation.
-                       return true
-               }
-               // Internal linking, for both ELF and Mach-O.
-               // Build a PLT entry and change the relocation target to that entry.
-               addpltsym(ctxt, targ)
-               r.Sym = ctxt.Syms.Lookup(".plt", 0)
-               r.Add = int64(targ.Plt())
-               return true
-
-       case objabi.R_ADDR:
-               if s.Type == sym.STEXT && ctxt.IsELF {
-                       if ctxt.HeadType == objabi.Hsolaris {
-                               addpltsym(ctxt, targ)
-                               r.Sym = ctxt.Syms.Lookup(".plt", 0)
-                               r.Add += int64(targ.Plt())
-                               return true
-                       }
-                       // The code is asking for the address of an external
-                       // function. We provide it with the address of the
-                       // correspondent GOT symbol.
-                       addgotsym(ctxt, targ)
-
-                       r.Sym = ctxt.Syms.Lookup(".got", 0)
-                       r.Add += int64(targ.Got())
-                       return true
-               }
-
-               // Process dynamic relocations for the data sections.
-               if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal {
-                       // When internally linking, generate dynamic relocations
-                       // for all typical R_ADDR relocations. The exception
-                       // are those R_ADDR that are created as part of generating
-                       // the dynamic relocations and must be resolved statically.
-                       //
-                       // There are three phases relevant to understanding this:
-                       //
-                       //      dodata()  // we are here
-                       //      address() // symbol address assignment
-                       //      reloc()   // resolution of static R_ADDR relocs
-                       //
-                       // At this point symbol addresses have not been
-                       // assigned yet (as the final size of the .rela section
-                       // will affect the addresses), and so we cannot write
-                       // the Elf64_Rela.r_offset now. Instead we delay it
-                       // until after the 'address' phase of the linker is
-                       // complete. We do this via Addaddrplus, which creates
-                       // a new R_ADDR relocation which will be resolved in
-                       // the 'reloc' phase.
-                       //
-                       // These synthetic static R_ADDR relocs must be skipped
-                       // now, or else we will be caught in an infinite loop
-                       // of generating synthetic relocs for our synthetic
-                       // relocs.
-                       //
-                       // Furthermore, the rela sections contain dynamic
-                       // relocations with R_ADDR relocations on
-                       // Elf64_Rela.r_offset. This field should contain the
-                       // symbol offset as determined by reloc(), not the
-                       // final dynamically linked address as a dynamic
-                       // relocation would provide.
-                       switch s.Name {
-                       case ".dynsym", ".rela", ".rela.plt", ".got.plt", ".dynamic":
-                               return false
-                       }
-               } else {
-                       // Either internally linking a static executable,
-                       // in which case we can resolve these relocations
-                       // statically in the 'reloc' phase, or externally
-                       // linking, in which case the relocation will be
-                       // prepared in the 'reloc' phase and passed to the
-                       // external linker in the 'asmb' phase.
-                       if s.Type != sym.SDATA && s.Type != sym.SRODATA {
-                               break
-                       }
-               }
-
-               if ctxt.IsELF {
-                       // Generate R_X86_64_RELATIVE relocations for best
-                       // efficiency in the dynamic linker.
-                       //
-                       // As noted above, symbol addresses have not been
-                       // assigned yet, so we can't generate the final reloc
-                       // entry yet. We ultimately want:
-                       //
-                       // r_offset = s + r.Off
-                       // r_info = R_X86_64_RELATIVE
-                       // r_addend = targ + r.Add
-                       //
-                       // The dynamic linker will set *offset = base address +
-                       // addend.
-                       //
-                       // AddAddrPlus is used for r_offset and r_addend to
-                       // generate new R_ADDR relocations that will update
-                       // these fields in the 'reloc' phase.
-                       rela := ctxt.Syms.Lookup(".rela", 0)
-                       rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
-                       if r.Siz == 8 {
-                               rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_X86_64_RELATIVE)))
-                       } else {
-                               ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
-                       }
-                       rela.AddAddrPlus(ctxt.Arch, targ, int64(r.Add))
-                       // Not mark r done here. So we still apply it statically,
-                       // so in the file content we'll also have the right offset
-                       // to the relocation target. So it can be examined statically
-                       // (e.g. go version).
-                       return true
-               }
-
-               if ctxt.HeadType == objabi.Hdarwin && s.Size == int64(ctxt.Arch.PtrSize) && r.Off == 0 {
-                       // Mach-O relocations are a royal pain to lay out.
-                       // They use a compact stateful bytecode representation
-                       // that is too much bother to deal with.
-                       // Instead, interpret the C declaration
-                       //      void *_Cvar_stderr = &stderr;
-                       // as making _Cvar_stderr the name of a GOT entry
-                       // for stderr. This is separate from the usual GOT entry,
-                       // just in case the C code assigns to the variable,
-                       // and of course it only works for single pointers,
-                       // but we only need to support cgo and that's all it needs.
-                       ld.Adddynsym(ctxt, targ)
-
-                       got := ctxt.Syms.Lookup(".got", 0)
-                       s.Type = got.Type
-                       s.Attr |= sym.AttrSubSymbol
-                       s.Outer = got
-                       s.Sub = got.Sub
-                       got.Sub = s
-                       s.Value = got.Size
-                       got.AddUint64(ctxt.Arch, 0)
-                       ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(targ.Dynid))
-                       r.Type = objabi.ElfRelocOffset // ignore during relocsym
-                       return true
-               }
-       }
-
-       return false
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-       ctxt.Out.Write64(uint64(sectoff))
-
-       elfsym := r.Xsym.ElfsymForReloc()
-       switch r.Type {
-       default:
-               return false
-       case objabi.R_ADDR:
-               if r.Siz == 4 {
-                       ctxt.Out.Write64(uint64(elf.R_X86_64_32) | uint64(elfsym)<<32)
-               } else if r.Siz == 8 {
-                       ctxt.Out.Write64(uint64(elf.R_X86_64_64) | uint64(elfsym)<<32)
-               } else {
-                       return false
-               }
-       case objabi.R_TLS_LE:
-               if r.Siz == 4 {
-                       ctxt.Out.Write64(uint64(elf.R_X86_64_TPOFF32) | uint64(elfsym)<<32)
-               } else {
-                       return false
-               }
-       case objabi.R_TLS_IE:
-               if r.Siz == 4 {
-                       ctxt.Out.Write64(uint64(elf.R_X86_64_GOTTPOFF) | uint64(elfsym)<<32)
-               } else {
-                       return false
-               }
-       case objabi.R_CALL:
-               if r.Siz == 4 {
-                       if r.Xsym.Type == sym.SDYNIMPORT {
-                               if ctxt.DynlinkingGo() {
-                                       ctxt.Out.Write64(uint64(elf.R_X86_64_PLT32) | uint64(elfsym)<<32)
-                               } else {
-                                       ctxt.Out.Write64(uint64(elf.R_X86_64_GOTPCREL) | uint64(elfsym)<<32)
-                               }
-                       } else {
-                               ctxt.Out.Write64(uint64(elf.R_X86_64_PC32) | uint64(elfsym)<<32)
-                       }
-               } else {
-                       return false
-               }
-       case objabi.R_PCREL:
-               if r.Siz == 4 {
-                       if r.Xsym.Type == sym.SDYNIMPORT && r.Xsym.ElfType() == elf.STT_FUNC {
-                               ctxt.Out.Write64(uint64(elf.R_X86_64_PLT32) | uint64(elfsym)<<32)
-                       } else {
-                               ctxt.Out.Write64(uint64(elf.R_X86_64_PC32) | uint64(elfsym)<<32)
-                       }
-               } else {
-                       return false
-               }
-       case objabi.R_GOTPCREL:
-               if r.Siz == 4 {
-                       ctxt.Out.Write64(uint64(elf.R_X86_64_GOTPCREL) | uint64(elfsym)<<32)
-               } else {
-                       return false
-               }
-       }
-
-       ctxt.Out.Write64(uint64(r.Xadd))
-       return true
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-       var v uint32
-
-       rs := r.Xsym
-
-       if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_PCREL || r.Type == objabi.R_GOTPCREL || r.Type == objabi.R_CALL {
-               if rs.Dynid < 0 {
-                       ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
-                       return false
-               }
-
-               v = uint32(rs.Dynid)
-               v |= 1 << 27 // external relocation
-       } else {
-               v = uint32(rs.Sect.Extnum)
-               if v == 0 {
-                       ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
-                       return false
-               }
-       }
-
-       switch r.Type {
-       default:
-               return false
-
-       case objabi.R_ADDR:
-               v |= ld.MACHO_X86_64_RELOC_UNSIGNED << 28
-
-       case objabi.R_CALL:
-               v |= 1 << 24 // pc-relative bit
-               v |= ld.MACHO_X86_64_RELOC_BRANCH << 28
-
-               // NOTE: Only works with 'external' relocation. Forced above.
-       case objabi.R_PCREL:
-               v |= 1 << 24 // pc-relative bit
-               v |= ld.MACHO_X86_64_RELOC_SIGNED << 28
-       case objabi.R_GOTPCREL:
-               v |= 1 << 24 // pc-relative bit
-               v |= ld.MACHO_X86_64_RELOC_GOT_LOAD << 28
-       }
-
-       switch r.Siz {
-       default:
-               return false
-
-       case 1:
-               v |= 0 << 25
-
-       case 2:
-               v |= 1 << 25
-
-       case 4:
-               v |= 2 << 25
-
-       case 8:
-               v |= 3 << 25
-       }
-
-       out.Write32(uint32(sectoff))
-       out.Write32(v)
-       return true
-}
-
-func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-       var v uint32
-
-       rs := r.Xsym
-
-       if rs.Dynid < 0 {
-               ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
-               return false
-       }
-
-       out.Write32(uint32(sectoff))
-       out.Write32(uint32(rs.Dynid))
-
-       switch r.Type {
-       default:
-               return false
-
-       case objabi.R_DWARFSECREF:
-               v = ld.IMAGE_REL_AMD64_SECREL
-
-       case objabi.R_ADDR:
-               if r.Siz == 8 {
-                       v = ld.IMAGE_REL_AMD64_ADDR64
-               } else {
-                       v = ld.IMAGE_REL_AMD64_ADDR32
-               }
-
-       case objabi.R_CALL,
-               objabi.R_PCREL:
-               v = ld.IMAGE_REL_AMD64_REL32
-       }
-
-       out.Write16(uint16(v))
-
-       return true
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-       return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-       log.Fatalf("unexpected relocation variant")
-       return t
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-       plt := ctxt.Syms.Lookup(".plt", 0)
-       got := ctxt.Syms.Lookup(".got.plt", 0)
-       if plt.Size == 0 {
-               // pushq got+8(IP)
-               plt.AddUint8(0xff)
-
-               plt.AddUint8(0x35)
-               plt.AddPCRelPlus(ctxt.Arch, got, 8)
-
-               // jmpq got+16(IP)
-               plt.AddUint8(0xff)
-
-               plt.AddUint8(0x25)
-               plt.AddPCRelPlus(ctxt.Arch, got, 16)
-
-               // nopl 0(AX)
-               plt.AddUint32(ctxt.Arch, 0x00401f0f)
-
-               // assume got->size == 0 too
-               got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
-
-               got.AddUint64(ctxt.Arch, 0)
-               got.AddUint64(ctxt.Arch, 0)
-       }
-}
-
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
-       if s.Plt() >= 0 {
-               return
-       }
-
-       ld.Adddynsym(ctxt, s)
-
-       if ctxt.IsELF {
-               plt := ctxt.Syms.Lookup(".plt", 0)
-               got := ctxt.Syms.Lookup(".got.plt", 0)
-               rela := ctxt.Syms.Lookup(".rela.plt", 0)
-               if plt.Size == 0 {
-                       elfsetupplt(ctxt)
-               }
-
-               // jmpq *got+size(IP)
-               plt.AddUint8(0xff)
-
-               plt.AddUint8(0x25)
-               plt.AddPCRelPlus(ctxt.Arch, got, got.Size)
-
-               // add to got: pointer to current pos in plt
-               got.AddAddrPlus(ctxt.Arch, plt, plt.Size)
-
-               // pushq $x
-               plt.AddUint8(0x68)
-
-               plt.AddUint32(ctxt.Arch, uint32((got.Size-24-8)/8))
-
-               // jmpq .plt
-               plt.AddUint8(0xe9)
-
-               plt.AddUint32(ctxt.Arch, uint32(-(plt.Size + 4)))
-
-               // rela
-               rela.AddAddrPlus(ctxt.Arch, got, got.Size-8)
-
-               rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_X86_64_JMP_SLOT)))
-               rela.AddUint64(ctxt.Arch, 0)
-
-               s.SetPlt(int32(plt.Size - 16))
-       } else if ctxt.HeadType == objabi.Hdarwin {
-               // To do lazy symbol lookup right, we're supposed
-               // to tell the dynamic loader which library each
-               // symbol comes from and format the link info
-               // section just so. I'm too lazy (ha!) to do that
-               // so for now we'll just use non-lazy pointers,
-               // which don't need to be told which library to use.
-               //
-               // https://networkpx.blogspot.com/2009/09/about-lcdyldinfoonly-command.html
-               // has details about what we're avoiding.
-
-               addgotsym(ctxt, s)
-               plt := ctxt.Syms.Lookup(".plt", 0)
-
-               ctxt.Syms.Lookup(".linkedit.plt", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
-
-               // jmpq *got+size(IP)
-               s.SetPlt(int32(plt.Size))
-
-               plt.AddUint8(0xff)
-               plt.AddUint8(0x25)
-               plt.AddPCRelPlus(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got()))
-       } else {
-               ld.Errorf(s, "addpltsym: unsupported binary format")
-       }
-}
-
-func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
-       if s.Got() >= 0 {
-               return
-       }
-
-       ld.Adddynsym(ctxt, s)
-       got := ctxt.Syms.Lookup(".got", 0)
-       s.SetGot(int32(got.Size))
-       got.AddUint64(ctxt.Arch, 0)
-
-       if ctxt.IsELF {
-               rela := ctxt.Syms.Lookup(".rela", 0)
-               rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
-               rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_X86_64_GLOB_DAT)))
-               rela.AddUint64(ctxt.Arch, 0)
-       } else if ctxt.HeadType == objabi.Hdarwin {
-               ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
-       } else {
-               ld.Errorf(s, "addgotsym: unsupported binary format")
-       }
-}
-
-func asmb(ctxt *ld.Link) {
-       if ctxt.IsELF {
-               ld.Asmbelfsetup()
-       }
-
-       sect := ld.Segtext.Sections[0]
-       ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-       // 0xCC is INT $3 - breakpoint instruction
-       ld.CodeblkPad(ctxt, int64(sect.Vaddr), int64(sect.Length), []byte{0xCC})
-       for _, sect = range ld.Segtext.Sections[1:] {
-               ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-               ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-       }
-
-       if ld.Segrodata.Filelen > 0 {
-               ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-               ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-       }
-       if ld.Segrelrodata.Filelen > 0 {
-               ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
-               ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
-       }
-
-       ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-       ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-       ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-       ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-       machlink := int64(0)
-       if ctxt.HeadType == objabi.Hdarwin {
-               machlink = ld.Domacholink(ctxt)
-       }
-
-       switch ctxt.HeadType {
-       default:
-               ld.Errorf(nil, "unknown header type %v", ctxt.HeadType)
-               fallthrough
-
-       case objabi.Hplan9:
-               break
-
-       case objabi.Hdarwin:
-               ld.Flag8 = true /* 64-bit addresses */
-
-       case objabi.Hlinux,
-               objabi.Hfreebsd,
-               objabi.Hnetbsd,
-               objabi.Hopenbsd,
-               objabi.Hdragonfly,
-               objabi.Hsolaris:
-               ld.Flag8 = true /* 64-bit addresses */
-
-       case objabi.Hwindows:
-               break
-       }
-
-       ld.Symsize = 0
-       ld.Spsize = 0
-       ld.Lcsize = 0
-       symo := int64(0)
-       if !*ld.FlagS {
-               switch ctxt.HeadType {
-               default:
-               case objabi.Hplan9:
-                       *ld.FlagS = true
-                       symo = int64(ld.Segdata.Fileoff + ld.Segdata.Filelen)
-
-               case objabi.Hdarwin:
-                       symo = int64(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(*ld.FlagRound))) + uint64(machlink))
-
-               case objabi.Hlinux,
-                       objabi.Hfreebsd,
-                       objabi.Hnetbsd,
-                       objabi.Hopenbsd,
-                       objabi.Hdragonfly,
-                       objabi.Hsolaris:
-                       symo = int64(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-                       symo = ld.Rnd(symo, int64(*ld.FlagRound))
-
-               case objabi.Hwindows:
-                       symo = int64(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-                       symo = ld.Rnd(symo, ld.PEFILEALIGN)
-               }
-
-               ctxt.Out.SeekSet(symo)
-               switch ctxt.HeadType {
-               default:
-                       if ctxt.IsELF {
-                               ctxt.Out.SeekSet(symo)
-                               ld.Asmelfsym(ctxt)
-                               ctxt.Out.Flush()
-                               ctxt.Out.Write(ld.Elfstrdat)
-
-                               if ctxt.LinkMode == ld.LinkExternal {
-                                       ld.Elfemitreloc(ctxt)
-                               }
-                       }
-
-               case objabi.Hplan9:
-                       ld.Asmplan9sym(ctxt)
-                       ctxt.Out.Flush()
-
-                       sym := ctxt.Syms.Lookup("pclntab", 0)
-                       if sym != nil {
-                               ld.Lcsize = int32(len(sym.P))
-                               ctxt.Out.Write(sym.P)
-                               ctxt.Out.Flush()
-                       }
-
-               case objabi.Hwindows:
-                       // Do nothing
-
-               case objabi.Hdarwin:
-                       if ctxt.LinkMode == ld.LinkExternal {
-                               ld.Machoemitreloc(ctxt)
-                       }
-               }
-       }
-
-       ctxt.Out.SeekSet(0)
-       switch ctxt.HeadType {
-       default:
-       case objabi.Hplan9: /* plan9 */
-               magic := int32(4*26*26 + 7)
-
-               magic |= 0x00008000                           /* fat header */
-               ctxt.Out.Write32b(uint32(magic))              /* magic */
-               ctxt.Out.Write32b(uint32(ld.Segtext.Filelen)) /* sizes */
-               ctxt.Out.Write32b(uint32(ld.Segdata.Filelen))
-               ctxt.Out.Write32b(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-               ctxt.Out.Write32b(uint32(ld.Symsize)) /* nsyms */
-               vl := ld.Entryvalue(ctxt)
-               ctxt.Out.Write32b(PADDR(uint32(vl))) /* va of entry */
-               ctxt.Out.Write32b(uint32(ld.Spsize)) /* sp offsets */
-               ctxt.Out.Write32b(uint32(ld.Lcsize)) /* line offsets */
-               ctxt.Out.Write64b(uint64(vl))        /* va of entry */
-
-       case objabi.Hdarwin:
-               ld.Asmbmacho(ctxt)
-
-       case objabi.Hlinux,
-               objabi.Hfreebsd,
-               objabi.Hnetbsd,
-               objabi.Hopenbsd,
-               objabi.Hdragonfly,
-               objabi.Hsolaris:
-               ld.Asmbelf(ctxt, symo)
-
-       case objabi.Hwindows:
-               ld.Asmbpe(ctxt)
-       }
-
-       ctxt.Out.Flush()
-}
-
-func tlsIEtoLE(s *sym.Symbol, off, size int) {
-       // Transform the PC-relative instruction into a constant load.
-       // That is,
-       //
-       //      MOVQ X(IP), REG  ->  MOVQ $Y, REG
-       //
-       // To determine the instruction and register, we study the op codes.
-       // Consult an AMD64 instruction encoding guide to decipher this.
-       if off < 3 {
-               log.Fatal("R_X86_64_GOTTPOFF reloc not preceded by MOVQ or ADDQ instruction")
-       }
-       op := s.P[off-3 : off]
-       reg := op[2] >> 3
-
-       if op[1] == 0x8b || reg == 4 {
-               // MOVQ
-               if op[0] == 0x4c {
-                       op[0] = 0x49
-               } else if size == 4 && op[0] == 0x44 {
-                       op[0] = 0x41
-               }
-               if op[1] == 0x8b {
-                       op[1] = 0xc7
-               } else {
-                       op[1] = 0x81 // special case for SP
-               }
-               op[2] = 0xc0 | reg
-       } else {
-               // An alternate op is ADDQ. This is handled by GNU gold,
-               // but right now is not generated by the Go compiler:
-               //      ADDQ X(IP), REG  ->  ADDQ $Y, REG
-               // Consider adding support for it here.
-               log.Fatalf("expected TLS IE op to be MOVQ, got %v", op)
-       }
-}
diff --git a/src/cmd/oldlink/internal/amd64/l.go b/src/cmd/oldlink/internal/amd64/l.go
deleted file mode 100644 (file)
index 393da6b..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// Inferno utils/6l/l.h
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package amd64
-
-const (
-       maxAlign  = 32 // max data alignment
-       minAlign  = 1  // min data alignment
-       funcAlign = 16
-)
-
-/* Used by ../internal/ld/dwarf.go */
-const (
-       dwarfRegSP = 7
-       dwarfRegLR = 16
-)
diff --git a/src/cmd/oldlink/internal/amd64/obj.go b/src/cmd/oldlink/internal/amd64/obj.go
deleted file mode 100644 (file)
index 655d9f1..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-// Inferno utils/6l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package amd64
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-       arch := sys.ArchAMD64
-
-       theArch := ld.Arch{
-               Funcalign:  funcAlign,
-               Maxalign:   maxAlign,
-               Minalign:   minAlign,
-               Dwarfregsp: dwarfRegSP,
-               Dwarfreglr: dwarfRegLR,
-
-               Adddynrel:        adddynrel,
-               Archinit:         archinit,
-               Archreloc:        archreloc,
-               Archrelocvariant: archrelocvariant,
-               Asmb:             asmb,
-               Asmb2:            asmb2,
-               Elfreloc1:        elfreloc1,
-               Elfsetupplt:      elfsetupplt,
-               Gentext:          gentext,
-               Machoreloc1:      machoreloc1,
-               PEreloc1:         pereloc1,
-               TLSIEtoLE:        tlsIEtoLE,
-
-               Linuxdynld:     "/lib64/ld-linux-x86-64.so.2",
-               Freebsddynld:   "/libexec/ld-elf.so.1",
-               Openbsddynld:   "/usr/libexec/ld.so",
-               Netbsddynld:    "/libexec/ld.elf_so",
-               Dragonflydynld: "/usr/libexec/ld-elf.so.2",
-               Solarisdynld:   "/lib/amd64/ld.so.1",
-       }
-
-       return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-       switch ctxt.HeadType {
-       default:
-               ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-
-       case objabi.Hplan9: /* plan 9 */
-               ld.HEADR = 32 + 8
-
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = 0x200000 + int64(ld.HEADR)
-               }
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 0x200000
-               }
-
-       case objabi.Hdarwin: /* apple MACH */
-               ld.HEADR = ld.INITIAL_MACHO_HEADR
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 4096
-               }
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = 0x1000000 + int64(ld.HEADR)
-               }
-
-       case objabi.Hlinux, /* elf64 executable */
-               objabi.Hfreebsd,   /* freebsd */
-               objabi.Hnetbsd,    /* netbsd */
-               objabi.Hopenbsd,   /* openbsd */
-               objabi.Hdragonfly, /* dragonfly */
-               objabi.Hsolaris:   /* solaris */
-               ld.Elfinit(ctxt)
-
-               ld.HEADR = ld.ELFRESERVE
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = (1 << 22) + int64(ld.HEADR)
-               }
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 4096
-               }
-
-       case objabi.Hwindows: /* PE executable */
-               // ld.HEADR, ld.FlagTextAddr, ld.FlagRound are set in ld.Peinit
-               return
-       }
-}
diff --git a/src/cmd/oldlink/internal/arm/asm.go b/src/cmd/oldlink/internal/arm/asm.go
deleted file mode 100644 (file)
index de61735..0000000
+++ /dev/null
@@ -1,786 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package arm
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/ld"
-       "cmd/oldlink/internal/sym"
-       "debug/elf"
-       "fmt"
-       "log"
-)
-
-// This assembler:
-//
-//         .align 2
-// local.dso_init:
-//         ldr r0, .Lmoduledata
-// .Lloadfrom:
-//         ldr r0, [r0]
-//         b runtime.addmoduledata@plt
-// .align 2
-// .Lmoduledata:
-//         .word local.moduledata(GOT_PREL) + (. - (.Lloadfrom + 4))
-// assembles to:
-//
-// 00000000 <local.dso_init>:
-//    0:        e59f0004        ldr     r0, [pc, #4]    ; c <local.dso_init+0xc>
-//    4:        e5900000        ldr     r0, [r0]
-//    8:        eafffffe        b       0 <runtime.addmoduledata>
-//                      8: R_ARM_JUMP24 runtime.addmoduledata
-//    c:        00000004        .word   0x00000004
-//                      c: R_ARM_GOT_PREL       local.moduledata
-
-func gentext(ctxt *ld.Link) {
-       if !ctxt.DynlinkingGo() {
-               return
-       }
-       addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-       if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
-               // we're linking a module containing the runtime -> no need for
-               // an init function
-               return
-       }
-       addmoduledata.Attr |= sym.AttrReachable
-       initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-       initfunc.Type = sym.STEXT
-       initfunc.Attr |= sym.AttrLocal
-       initfunc.Attr |= sym.AttrReachable
-       o := func(op uint32) {
-               initfunc.AddUint32(ctxt.Arch, op)
-       }
-       o(0xe59f0004)
-       o(0xe08f0000)
-
-       o(0xeafffffe)
-       rel := initfunc.AddRel()
-       rel.Off = 8
-       rel.Siz = 4
-       rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-       rel.Type = objabi.R_CALLARM
-       rel.Add = 0xeafffffe // vomit
-
-       o(0x00000000)
-       rel = initfunc.AddRel()
-       rel.Off = 12
-       rel.Siz = 4
-       rel.Sym = ctxt.Moduledata
-       rel.Type = objabi.R_PCREL
-       rel.Add = 4
-
-       if ctxt.BuildMode == ld.BuildModePlugin {
-               ctxt.Textp = append(ctxt.Textp, addmoduledata)
-       }
-       ctxt.Textp = append(ctxt.Textp, initfunc)
-       initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-       initarray_entry.Attr |= sym.AttrReachable
-       initarray_entry.Attr |= sym.AttrLocal
-       initarray_entry.Type = sym.SINITARR
-       initarray_entry.AddAddr(ctxt.Arch, initfunc)
-}
-
-// Preserve highest 8 bits of a, and do addition to lower 24-bit
-// of a and b; used to adjust ARM branch instruction's target
-func braddoff(a int32, b int32) int32 {
-       return int32((uint32(a))&0xff000000 | 0x00ffffff&uint32(a+b))
-}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-       targ := r.Sym
-
-       switch r.Type {
-       default:
-               if r.Type >= objabi.ElfRelocOffset {
-                       ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
-                       return false
-               }
-
-               // Handle relocations found in ELF object files.
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PLT32):
-               r.Type = objabi.R_CALLARM
-
-               if targ.Type == sym.SDYNIMPORT {
-                       addpltsym(ctxt, targ)
-                       r.Sym = ctxt.Syms.Lookup(".plt", 0)
-                       r.Add = int64(braddoff(int32(r.Add), targ.Plt()/4))
-               }
-
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_THM_PC22): // R_ARM_THM_CALL
-               ld.Exitf("R_ARM_THM_CALL, are you using -marm?")
-               return false
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOT32): // R_ARM_GOT_BREL
-               if targ.Type != sym.SDYNIMPORT {
-                       addgotsyminternal(ctxt, targ)
-               } else {
-                       addgotsym(ctxt, targ)
-               }
-
-               r.Type = objabi.R_CONST // write r->add during relocsym
-               r.Sym = nil
-               r.Add += int64(targ.Got())
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOT_PREL): // GOT(nil) + A - nil
-               if targ.Type != sym.SDYNIMPORT {
-                       addgotsyminternal(ctxt, targ)
-               } else {
-                       addgotsym(ctxt, targ)
-               }
-
-               r.Type = objabi.R_PCREL
-               r.Sym = ctxt.Syms.Lookup(".got", 0)
-               r.Add += int64(targ.Got()) + 4
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOTOFF): // R_ARM_GOTOFF32
-               r.Type = objabi.R_GOTOFF
-
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOTPC): // R_ARM_BASE_PREL
-               r.Type = objabi.R_PCREL
-
-               r.Sym = ctxt.Syms.Lookup(".got", 0)
-               r.Add += 4
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_CALL):
-               r.Type = objabi.R_CALLARM
-               if targ.Type == sym.SDYNIMPORT {
-                       addpltsym(ctxt, targ)
-                       r.Sym = ctxt.Syms.Lookup(".plt", 0)
-                       r.Add = int64(braddoff(int32(r.Add), targ.Plt()/4))
-               }
-
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_REL32): // R_ARM_REL32
-               r.Type = objabi.R_PCREL
-
-               r.Add += 4
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_ABS32):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected R_ARM_ABS32 relocation for dynamic symbol %s", targ.Name)
-               }
-               r.Type = objabi.R_ADDR
-               return true
-
-               // we can just ignore this, because we are targeting ARM V5+ anyway
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_V4BX):
-               if r.Sym != nil {
-                       // R_ARM_V4BX is ABS relocation, so this symbol is a dummy symbol, ignore it
-                       r.Sym.Type = 0
-               }
-
-               r.Sym = nil
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PC24),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_JUMP24):
-               r.Type = objabi.R_CALLARM
-               if targ.Type == sym.SDYNIMPORT {
-                       addpltsym(ctxt, targ)
-                       r.Sym = ctxt.Syms.Lookup(".plt", 0)
-                       r.Add = int64(braddoff(int32(r.Add), targ.Plt()/4))
-               }
-
-               return true
-       }
-
-       // Handle references to ELF symbols from our own object files.
-       if targ.Type != sym.SDYNIMPORT {
-               return true
-       }
-
-       switch r.Type {
-       case objabi.R_CALLARM:
-               if ctxt.LinkMode == ld.LinkExternal {
-                       // External linker will do this relocation.
-                       return true
-               }
-               addpltsym(ctxt, targ)
-               r.Sym = ctxt.Syms.Lookup(".plt", 0)
-               r.Add = int64(targ.Plt())
-               return true
-
-       case objabi.R_ADDR:
-               if s.Type != sym.SDATA {
-                       break
-               }
-               if ctxt.IsELF {
-                       ld.Adddynsym(ctxt, targ)
-                       rel := ctxt.Syms.Lookup(".rel", 0)
-                       rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
-                       rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_ARM_GLOB_DAT))) // we need a nil + A dynamic reloc
-                       r.Type = objabi.R_CONST                                                                   // write r->add during relocsym
-                       r.Sym = nil
-                       return true
-               }
-       }
-
-       return false
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-       ctxt.Out.Write32(uint32(sectoff))
-
-       elfsym := r.Xsym.ElfsymForReloc()
-       switch r.Type {
-       default:
-               return false
-       case objabi.R_ADDR:
-               if r.Siz == 4 {
-                       ctxt.Out.Write32(uint32(elf.R_ARM_ABS32) | uint32(elfsym)<<8)
-               } else {
-                       return false
-               }
-       case objabi.R_PCREL:
-               if r.Siz == 4 {
-                       ctxt.Out.Write32(uint32(elf.R_ARM_REL32) | uint32(elfsym)<<8)
-               } else {
-                       return false
-               }
-       case objabi.R_CALLARM:
-               if r.Siz == 4 {
-                       if r.Add&0xff000000 == 0xeb000000 { // BL
-                               ctxt.Out.Write32(uint32(elf.R_ARM_CALL) | uint32(elfsym)<<8)
-                       } else {
-                               ctxt.Out.Write32(uint32(elf.R_ARM_JUMP24) | uint32(elfsym)<<8)
-                       }
-               } else {
-                       return false
-               }
-       case objabi.R_TLS_LE:
-               ctxt.Out.Write32(uint32(elf.R_ARM_TLS_LE32) | uint32(elfsym)<<8)
-       case objabi.R_TLS_IE:
-               ctxt.Out.Write32(uint32(elf.R_ARM_TLS_IE32) | uint32(elfsym)<<8)
-       case objabi.R_GOTPCREL:
-               if r.Siz == 4 {
-                       ctxt.Out.Write32(uint32(elf.R_ARM_GOT_PREL) | uint32(elfsym)<<8)
-               } else {
-                       return false
-               }
-       }
-
-       return true
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-       plt := ctxt.Syms.Lookup(".plt", 0)
-       got := ctxt.Syms.Lookup(".got.plt", 0)
-       if plt.Size == 0 {
-               // str lr, [sp, #-4]!
-               plt.AddUint32(ctxt.Arch, 0xe52de004)
-
-               // ldr lr, [pc, #4]
-               plt.AddUint32(ctxt.Arch, 0xe59fe004)
-
-               // add lr, pc, lr
-               plt.AddUint32(ctxt.Arch, 0xe08fe00e)
-
-               // ldr pc, [lr, #8]!
-               plt.AddUint32(ctxt.Arch, 0xe5bef008)
-
-               // .word &GLOBAL_OFFSET_TABLE[0] - .
-               plt.AddPCRelPlus(ctxt.Arch, got, 4)
-
-               // the first .plt entry requires 3 .plt.got entries
-               got.AddUint32(ctxt.Arch, 0)
-
-               got.AddUint32(ctxt.Arch, 0)
-               got.AddUint32(ctxt.Arch, 0)
-       }
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-       return false
-}
-
-func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-       rs := r.Xsym
-
-       if rs.Dynid < 0 {
-               ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
-               return false
-       }
-
-       out.Write32(uint32(sectoff))
-       out.Write32(uint32(rs.Dynid))
-
-       var v uint32
-       switch r.Type {
-       default:
-               // unsupported relocation type
-               return false
-
-       case objabi.R_DWARFSECREF:
-               v = ld.IMAGE_REL_ARM_SECREL
-
-       case objabi.R_ADDR:
-               v = ld.IMAGE_REL_ARM_ADDR32
-       }
-
-       out.Write16(uint16(v))
-
-       return true
-}
-
-// sign extend a 24-bit integer
-func signext24(x int64) int32 {
-       return (int32(x) << 8) >> 8
-}
-
-// encode an immediate in ARM's imm12 format. copied from ../../../internal/obj/arm/asm5.go
-func immrot(v uint32) uint32 {
-       for i := 0; i < 16; i++ {
-               if v&^0xff == 0 {
-                       return uint32(i<<8) | v | 1<<25
-               }
-               v = v<<2 | v>>30
-       }
-       return 0
-}
-
-// Convert the direct jump relocation r to refer to a trampoline if the target is too far
-func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
-       switch r.Type {
-       case objabi.R_CALLARM:
-               // r.Add is the instruction
-               // low 24-bit encodes the target address
-               t := (ld.Symaddr(r.Sym) + int64(signext24(r.Add&0xffffff)*4) - (s.Value + int64(r.Off))) / 4
-               if t > 0x7fffff || t < -0x800000 || (*ld.FlagDebugTramp > 1 && s.File != r.Sym.File) {
-                       // direct call too far, need to insert trampoline.
-                       // look up existing trampolines first. if we found one within the range
-                       // of direct call, we can reuse it. otherwise create a new one.
-                       offset := (signext24(r.Add&0xffffff) + 2) * 4
-                       var tramp *sym.Symbol
-                       for i := 0; ; i++ {
-                               name := r.Sym.Name + fmt.Sprintf("%+d-tramp%d", offset, i)
-                               tramp = ctxt.Syms.Lookup(name, int(r.Sym.Version))
-                               if tramp.Type == sym.SDYNIMPORT {
-                                       // don't reuse trampoline defined in other module
-                                       continue
-                               }
-                               if tramp.Value == 0 {
-                                       // either the trampoline does not exist -- we need to create one,
-                                       // or found one the address which is not assigned -- this will be
-                                       // laid down immediately after the current function. use this one.
-                                       break
-                               }
-
-                               t = (ld.Symaddr(tramp) - 8 - (s.Value + int64(r.Off))) / 4
-                               if t >= -0x800000 && t < 0x7fffff {
-                                       // found an existing trampoline that is not too far
-                                       // we can just use it
-                                       break
-                               }
-                       }
-                       if tramp.Type == 0 {
-                               // trampoline does not exist, create one
-                               ctxt.AddTramp(tramp)
-                               if ctxt.DynlinkingGo() {
-                                       if immrot(uint32(offset)) == 0 {
-                                               ld.Errorf(s, "odd offset in dynlink direct call: %v+%d", r.Sym, offset)
-                                       }
-                                       gentrampdyn(ctxt.Arch, tramp, r.Sym, int64(offset))
-                               } else if ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE {
-                                       gentramppic(ctxt.Arch, tramp, r.Sym, int64(offset))
-                               } else {
-                                       gentramp(ctxt.Arch, ctxt.LinkMode, tramp, r.Sym, int64(offset))
-                               }
-                       }
-                       // modify reloc to point to tramp, which will be resolved later
-                       r.Sym = tramp
-                       r.Add = r.Add&0xff000000 | 0xfffffe // clear the offset embedded in the instruction
-                       r.Done = false
-               }
-       default:
-               ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
-       }
-}
-
-// generate a trampoline to target+offset
-func gentramp(arch *sys.Arch, linkmode ld.LinkMode, tramp, target *sym.Symbol, offset int64) {
-       tramp.Size = 12 // 3 instructions
-       tramp.P = make([]byte, tramp.Size)
-       t := ld.Symaddr(target) + offset
-       o1 := uint32(0xe5900000 | 11<<12 | 15<<16) // MOVW (R15), R11 // R15 is actual pc + 8
-       o2 := uint32(0xe12fff10 | 11)              // JMP  (R11)
-       o3 := uint32(t)                            // WORD $target
-       arch.ByteOrder.PutUint32(tramp.P, o1)
-       arch.ByteOrder.PutUint32(tramp.P[4:], o2)
-       arch.ByteOrder.PutUint32(tramp.P[8:], o3)
-
-       if linkmode == ld.LinkExternal {
-               r := tramp.AddRel()
-               r.Off = 8
-               r.Type = objabi.R_ADDR
-               r.Siz = 4
-               r.Sym = target
-               r.Add = offset
-       }
-}
-
-// generate a trampoline to target+offset in position independent code
-func gentramppic(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
-       tramp.Size = 16 // 4 instructions
-       tramp.P = make([]byte, tramp.Size)
-       o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 4)  // MOVW 4(R15), R11 // R15 is actual pc + 8
-       o2 := uint32(0xe0800000 | 11<<12 | 15<<16 | 11) // ADD R15, R11, R11
-       o3 := uint32(0xe12fff10 | 11)                   // JMP  (R11)
-       o4 := uint32(0)                                 // WORD $(target-pc) // filled in with relocation
-       arch.ByteOrder.PutUint32(tramp.P, o1)
-       arch.ByteOrder.PutUint32(tramp.P[4:], o2)
-       arch.ByteOrder.PutUint32(tramp.P[8:], o3)
-       arch.ByteOrder.PutUint32(tramp.P[12:], o4)
-
-       r := tramp.AddRel()
-       r.Off = 12
-       r.Type = objabi.R_PCREL
-       r.Siz = 4
-       r.Sym = target
-       r.Add = offset + 4
-}
-
-// generate a trampoline to target+offset in dynlink mode (using GOT)
-func gentrampdyn(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
-       tramp.Size = 20                                 // 5 instructions
-       o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 8)  // MOVW 8(R15), R11 // R15 is actual pc + 8
-       o2 := uint32(0xe0800000 | 11<<12 | 15<<16 | 11) // ADD R15, R11, R11
-       o3 := uint32(0xe5900000 | 11<<12 | 11<<16)      // MOVW (R11), R11
-       o4 := uint32(0xe12fff10 | 11)                   // JMP  (R11)
-       o5 := uint32(0)                                 // WORD $target@GOT // filled in with relocation
-       o6 := uint32(0)
-       if offset != 0 {
-               // insert an instruction to add offset
-               tramp.Size = 24 // 6 instructions
-               o6 = o5
-               o5 = o4
-               o4 = 0xe2800000 | 11<<12 | 11<<16 | immrot(uint32(offset)) // ADD $offset, R11, R11
-               o1 = uint32(0xe5900000 | 11<<12 | 15<<16 | 12)             // MOVW 12(R15), R11
-       }
-       tramp.P = make([]byte, tramp.Size)
-       arch.ByteOrder.PutUint32(tramp.P, o1)
-       arch.ByteOrder.PutUint32(tramp.P[4:], o2)
-       arch.ByteOrder.PutUint32(tramp.P[8:], o3)
-       arch.ByteOrder.PutUint32(tramp.P[12:], o4)
-       arch.ByteOrder.PutUint32(tramp.P[16:], o5)
-       if offset != 0 {
-               arch.ByteOrder.PutUint32(tramp.P[20:], o6)
-       }
-
-       r := tramp.AddRel()
-       r.Off = 16
-       r.Type = objabi.R_GOTPCREL
-       r.Siz = 4
-       r.Sym = target
-       r.Add = 8
-       if offset != 0 {
-               // increase reloc offset by 4 as we inserted an ADD instruction
-               r.Off = 20
-               r.Add = 12
-       }
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-       if ctxt.LinkMode == ld.LinkExternal {
-               switch r.Type {
-               case objabi.R_CALLARM:
-                       r.Done = false
-
-                       // set up addend for eventual relocation via outer symbol.
-                       rs := r.Sym
-
-                       r.Xadd = int64(signext24(r.Add & 0xffffff))
-                       r.Xadd *= 4
-                       for rs.Outer != nil {
-                               r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
-                               rs = rs.Outer
-                       }
-
-                       if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Type != sym.SUNDEFEXT && rs.Sect == nil {
-                               ld.Errorf(s, "missing section for %s", rs.Name)
-                       }
-                       r.Xsym = rs
-
-                       if r.Xadd/4 > 0x7fffff || r.Xadd/4 < -0x800000 {
-                               ld.Errorf(s, "direct call too far %d", r.Xadd/4)
-                       }
-
-                       return int64(braddoff(int32(0xff000000&uint32(r.Add)), int32(0xffffff&uint32(r.Xadd/4)))), true
-               }
-
-               return -1, false
-       }
-
-       switch r.Type {
-       case objabi.R_CONST:
-               return r.Add, true
-       case objabi.R_GOTOFF:
-               return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
-
-       // The following three arch specific relocations are only for generation of
-       // Linux/ARM ELF's PLT entry (3 assembler instruction)
-       case objabi.R_PLT0: // add ip, pc, #0xXX00000
-               if ld.Symaddr(ctxt.Syms.Lookup(".got.plt", 0)) < ld.Symaddr(ctxt.Syms.Lookup(".plt", 0)) {
-                       ld.Errorf(s, ".got.plt should be placed after .plt section.")
-               }
-               return 0xe28fc600 + (0xff & (int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add)) >> 20)), true
-       case objabi.R_PLT1: // add ip, ip, #0xYY000
-               return 0xe28cca00 + (0xff & (int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add+4)) >> 12)), true
-       case objabi.R_PLT2: // ldr pc, [ip, #0xZZZ]!
-               return 0xe5bcf000 + (0xfff & int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add+8))), true
-       case objabi.R_CALLARM: // bl XXXXXX or b YYYYYY
-               // r.Add is the instruction
-               // low 24-bit encodes the target address
-               t := (ld.Symaddr(r.Sym) + int64(signext24(r.Add&0xffffff)*4) - (s.Value + int64(r.Off))) / 4
-               if t > 0x7fffff || t < -0x800000 {
-                       ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
-               }
-               return int64(braddoff(int32(0xff000000&uint32(r.Add)), int32(0xffffff&t))), true
-       }
-
-       return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-       log.Fatalf("unexpected relocation variant")
-       return t
-}
-
-func addpltreloc(ctxt *ld.Link, plt *sym.Symbol, got *sym.Symbol, s *sym.Symbol, typ objabi.RelocType) {
-       r := plt.AddRel()
-       r.Sym = got
-       r.Off = int32(plt.Size)
-       r.Siz = 4
-       r.Type = typ
-       r.Add = int64(s.Got()) - 8
-
-       plt.Attr |= sym.AttrReachable
-       plt.Size += 4
-       plt.Grow(plt.Size)
-}
-
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
-       if s.Plt() >= 0 {
-               return
-       }
-
-       ld.Adddynsym(ctxt, s)
-
-       if ctxt.IsELF {
-               plt := ctxt.Syms.Lookup(".plt", 0)
-               got := ctxt.Syms.Lookup(".got.plt", 0)
-               rel := ctxt.Syms.Lookup(".rel.plt", 0)
-               if plt.Size == 0 {
-                       elfsetupplt(ctxt)
-               }
-
-               // .got entry
-               s.SetGot(int32(got.Size))
-
-               // In theory, all GOT should point to the first PLT entry,
-               // Linux/ARM's dynamic linker will do that for us, but FreeBSD/ARM's
-               // dynamic linker won't, so we'd better do it ourselves.
-               got.AddAddrPlus(ctxt.Arch, plt, 0)
-
-               // .plt entry, this depends on the .got entry
-               s.SetPlt(int32(plt.Size))
-
-               addpltreloc(ctxt, plt, got, s, objabi.R_PLT0) // add lr, pc, #0xXX00000
-               addpltreloc(ctxt, plt, got, s, objabi.R_PLT1) // add lr, lr, #0xYY000
-               addpltreloc(ctxt, plt, got, s, objabi.R_PLT2) // ldr pc, [lr, #0xZZZ]!
-
-               // rel
-               rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
-
-               rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_JUMP_SLOT)))
-       } else {
-               ld.Errorf(s, "addpltsym: unsupported binary format")
-       }
-}
-
-func addgotsyminternal(ctxt *ld.Link, s *sym.Symbol) {
-       if s.Got() >= 0 {
-               return
-       }
-
-       got := ctxt.Syms.Lookup(".got", 0)
-       s.SetGot(int32(got.Size))
-
-       got.AddAddrPlus(ctxt.Arch, s, 0)
-
-       if ctxt.IsELF {
-       } else {
-               ld.Errorf(s, "addgotsyminternal: unsupported binary format")
-       }
-}
-
-func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
-       if s.Got() >= 0 {
-               return
-       }
-
-       ld.Adddynsym(ctxt, s)
-       got := ctxt.Syms.Lookup(".got", 0)
-       s.SetGot(int32(got.Size))
-       got.AddUint32(ctxt.Arch, 0)
-
-       if ctxt.IsELF {
-               rel := ctxt.Syms.Lookup(".rel", 0)
-               rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
-               rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_GLOB_DAT)))
-       } else {
-               ld.Errorf(s, "addgotsym: unsupported binary format")
-       }
-}
-
-func asmb(ctxt *ld.Link) {
-       if ctxt.IsELF {
-               ld.Asmbelfsetup()
-       }
-
-       sect := ld.Segtext.Sections[0]
-       ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-       ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-       for _, sect = range ld.Segtext.Sections[1:] {
-               ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-               ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-       }
-
-       if ld.Segrodata.Filelen > 0 {
-               ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-               ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-       }
-       if ld.Segrelrodata.Filelen > 0 {
-               ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
-               ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
-       }
-
-       ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-       ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-       ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-       ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-       /* output symbol table */
-       ld.Symsize = 0
-
-       ld.Lcsize = 0
-       symo := uint32(0)
-       if !*ld.FlagS {
-               // TODO: rationalize
-               switch ctxt.HeadType {
-               default:
-                       if ctxt.IsELF {
-                               symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-                               symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
-                       }
-
-               case objabi.Hplan9:
-                       symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
-
-               case objabi.Hwindows:
-                       symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-                       symo = uint32(ld.Rnd(int64(symo), ld.PEFILEALIGN))
-               }
-
-               ctxt.Out.SeekSet(int64(symo))
-               switch ctxt.HeadType {
-               default:
-                       if ctxt.IsELF {
-                               ld.Asmelfsym(ctxt)
-                               ctxt.Out.Flush()
-                               ctxt.Out.Write(ld.Elfstrdat)
-
-                               if ctxt.LinkMode == ld.LinkExternal {
-                                       ld.Elfemitreloc(ctxt)
-                               }
-                       }
-
-               case objabi.Hplan9:
-                       ld.Asmplan9sym(ctxt)
-                       ctxt.Out.Flush()
-
-                       sym := ctxt.Syms.Lookup("pclntab", 0)
-                       if sym != nil {
-                               ld.Lcsize = int32(len(sym.P))
-                               ctxt.Out.Write(sym.P)
-                               ctxt.Out.Flush()
-                       }
-
-               case objabi.Hwindows:
-                       // Do nothing
-               }
-       }
-
-       ctxt.Out.SeekSet(0)
-       switch ctxt.HeadType {
-       default:
-       case objabi.Hplan9: /* plan 9 */
-               ctxt.Out.Write32b(0x647)                      /* magic */
-               ctxt.Out.Write32b(uint32(ld.Segtext.Filelen)) /* sizes */
-               ctxt.Out.Write32b(uint32(ld.Segdata.Filelen))
-               ctxt.Out.Write32b(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-               ctxt.Out.Write32b(uint32(ld.Symsize))          /* nsyms */
-               ctxt.Out.Write32b(uint32(ld.Entryvalue(ctxt))) /* va of entry */
-               ctxt.Out.Write32b(0)
-               ctxt.Out.Write32b(uint32(ld.Lcsize))
-
-       case objabi.Hlinux,
-               objabi.Hfreebsd,
-               objabi.Hnetbsd,
-               objabi.Hopenbsd:
-               ld.Asmbelf(ctxt, int64(symo))
-
-       case objabi.Hwindows:
-               ld.Asmbpe(ctxt)
-       }
-
-       ctxt.Out.Flush()
-       if *ld.FlagC {
-               fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
-               fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
-               fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
-               fmt.Printf("symsize=%d\n", ld.Symsize)
-               fmt.Printf("lcsize=%d\n", ld.Lcsize)
-               fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
-       }
-}
diff --git a/src/cmd/oldlink/internal/arm/l.go b/src/cmd/oldlink/internal/arm/l.go
deleted file mode 100644 (file)
index a83d26b..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package arm
-
-// Writing object files.
-
-// Inferno utils/5l/l.h
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/l.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-const (
-       maxAlign  = 8 // max data alignment
-       minAlign  = 1 // min data alignment
-       funcAlign = 4 // single-instruction alignment
-)
-
-/* Used by ../internal/ld/dwarf.go */
-const (
-       dwarfRegSP = 13
-       dwarfRegLR = 14
-)
diff --git a/src/cmd/oldlink/internal/arm/obj.go b/src/cmd/oldlink/internal/arm/obj.go
deleted file mode 100644 (file)
index c423937..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-// Inferno utils/5l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/obj.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package arm
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-       arch := sys.ArchARM
-
-       theArch := ld.Arch{
-               Funcalign:  funcAlign,
-               Maxalign:   maxAlign,
-               Minalign:   minAlign,
-               Dwarfregsp: dwarfRegSP,
-               Dwarfreglr: dwarfRegLR,
-
-               Adddynrel:        adddynrel,
-               Archinit:         archinit,
-               Archreloc:        archreloc,
-               Archrelocvariant: archrelocvariant,
-               Trampoline:       trampoline,
-               Asmb:             asmb,
-               Asmb2:            asmb2,
-               Elfreloc1:        elfreloc1,
-               Elfsetupplt:      elfsetupplt,
-               Gentext:          gentext,
-               Machoreloc1:      machoreloc1,
-               PEreloc1:         pereloc1,
-
-               Linuxdynld:     "/lib/ld-linux.so.3", // 2 for OABI, 3 for EABI
-               Freebsddynld:   "/usr/libexec/ld-elf.so.1",
-               Openbsddynld:   "/usr/libexec/ld.so",
-               Netbsddynld:    "/libexec/ld.elf_so",
-               Dragonflydynld: "XXX",
-               Solarisdynld:   "XXX",
-       }
-
-       return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-       switch ctxt.HeadType {
-       default:
-               ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-
-       case objabi.Hplan9: /* plan 9 */
-               ld.HEADR = 32
-
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = 4128
-               }
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 4096
-               }
-
-       case objabi.Hlinux, /* arm elf */
-               objabi.Hfreebsd,
-               objabi.Hnetbsd,
-               objabi.Hopenbsd:
-               *ld.FlagD = false
-               // with dynamic linking
-               ld.Elfinit(ctxt)
-               ld.HEADR = ld.ELFRESERVE
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
-               }
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 0x10000
-               }
-
-       case objabi.Hwindows: /* PE executable */
-               // ld.HEADR, ld.FlagTextAddr, ld.FlagRound are set in ld.Peinit
-               return
-       }
-}
diff --git a/src/cmd/oldlink/internal/arm64/asm.go b/src/cmd/oldlink/internal/arm64/asm.go
deleted file mode 100644 (file)
index a976712..0000000
+++ /dev/null
@@ -1,946 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package arm64
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/ld"
-       "cmd/oldlink/internal/sym"
-       "debug/elf"
-       "encoding/binary"
-       "fmt"
-       "log"
-)
-
-func gentext(ctxt *ld.Link) {
-       if !ctxt.DynlinkingGo() {
-               return
-       }
-       addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-       if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
-               // we're linking a module containing the runtime -> no need for
-               // an init function
-               return
-       }
-       addmoduledata.Attr |= sym.AttrReachable
-       initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-       initfunc.Type = sym.STEXT
-       initfunc.Attr |= sym.AttrLocal
-       initfunc.Attr |= sym.AttrReachable
-       o := func(op uint32) {
-               initfunc.AddUint32(ctxt.Arch, op)
-       }
-       // 0000000000000000 <local.dso_init>:
-       // 0:   90000000        adrp    x0, 0 <runtime.firstmoduledata>
-       //      0: R_AARCH64_ADR_PREL_PG_HI21   local.moduledata
-       // 4:   91000000        add     x0, x0, #0x0
-       //      4: R_AARCH64_ADD_ABS_LO12_NC    local.moduledata
-       o(0x90000000)
-       o(0x91000000)
-       rel := initfunc.AddRel()
-       rel.Off = 0
-       rel.Siz = 8
-       rel.Sym = ctxt.Moduledata
-       rel.Type = objabi.R_ADDRARM64
-
-       // 8:   14000000        b       0 <runtime.addmoduledata>
-       //      8: R_AARCH64_CALL26     runtime.addmoduledata
-       o(0x14000000)
-       rel = initfunc.AddRel()
-       rel.Off = 8
-       rel.Siz = 4
-       rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-       rel.Type = objabi.R_CALLARM64 // Really should be R_AARCH64_JUMP26 but doesn't seem to make any difference
-
-       if ctxt.BuildMode == ld.BuildModePlugin {
-               ctxt.Textp = append(ctxt.Textp, addmoduledata)
-       }
-       ctxt.Textp = append(ctxt.Textp, initfunc)
-       initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-       initarray_entry.Attr |= sym.AttrReachable
-       initarray_entry.Attr |= sym.AttrLocal
-       initarray_entry.Type = sym.SINITARR
-       initarray_entry.AddAddr(ctxt.Arch, initfunc)
-}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-       targ := r.Sym
-
-       switch r.Type {
-       default:
-               if r.Type >= objabi.ElfRelocOffset {
-                       ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
-                       return false
-               }
-
-       // Handle relocations found in ELF object files.
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_PREL32):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected R_AARCH64_PREL32 relocation for dynamic symbol %s", targ.Name)
-               }
-               // TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
-               // sense and should be removed when someone has thought about it properly.
-               if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
-                       ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
-               }
-               r.Type = objabi.R_PCREL
-               r.Add += 4
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_PREL64):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected R_AARCH64_PREL64 relocation for dynamic symbol %s", targ.Name)
-               }
-               if targ.Type == 0 || targ.Type == sym.SXREF {
-                       ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
-               }
-               r.Type = objabi.R_PCREL
-               r.Add += 8
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_CALL26),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_JUMP26):
-               if targ.Type == sym.SDYNIMPORT {
-                       addpltsym(ctxt, targ)
-                       r.Sym = ctxt.Syms.Lookup(".plt", 0)
-                       r.Add += int64(targ.Plt())
-               }
-               if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
-                       ld.Errorf(s, "unknown symbol %s in callarm64", targ.Name)
-               }
-               r.Type = objabi.R_CALLARM64
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_ADR_GOT_PAGE),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_LD64_GOT_LO12_NC):
-               if targ.Type != sym.SDYNIMPORT {
-                       // have symbol
-                       // TODO: turn LDR of GOT entry into ADR of symbol itself
-               }
-
-               // fall back to using GOT
-               // TODO: just needs relocation, no need to put in .dynsym
-               addgotsym(ctxt, targ)
-
-               r.Type = objabi.R_ARM64_GOT
-               r.Sym = ctxt.Syms.Lookup(".got", 0)
-               r.Add += int64(targ.Got())
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_ADR_PREL_PG_HI21),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_ADD_ABS_LO12_NC):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
-               }
-               if targ.Type == 0 || targ.Type == sym.SXREF {
-                       ld.Errorf(s, "unknown symbol %s", targ.Name)
-               }
-               r.Type = objabi.R_ARM64_PCREL
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_ABS64):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected R_AARCH64_ABS64 relocation for dynamic symbol %s", targ.Name)
-               }
-               r.Type = objabi.R_ADDR
-               if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal {
-                       // For internal linking PIE, this R_ADDR relocation cannot
-                       // be resolved statically. We need to generate a dynamic
-                       // relocation. Let the code below handle it.
-                       break
-               }
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_LDST8_ABS_LO12_NC):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
-               }
-               r.Type = objabi.R_ARM64_LDST8
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_LDST32_ABS_LO12_NC):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
-               }
-               r.Type = objabi.R_ARM64_LDST32
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_LDST64_ABS_LO12_NC):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
-               }
-               r.Type = objabi.R_ARM64_LDST64
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_LDST128_ABS_LO12_NC):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
-               }
-               r.Type = objabi.R_ARM64_LDST128
-               return true
-       }
-
-       switch r.Type {
-       case objabi.R_CALL,
-               objabi.R_PCREL,
-               objabi.R_CALLARM64:
-               if targ.Type != sym.SDYNIMPORT {
-                       // nothing to do, the relocation will be laid out in reloc
-                       return true
-               }
-               if ctxt.LinkMode == ld.LinkExternal {
-                       // External linker will do this relocation.
-                       return true
-               }
-
-       case objabi.R_ADDR:
-               if s.Type == sym.STEXT && ctxt.IsELF {
-                       // The code is asking for the address of an external
-                       // function. We provide it with the address of the
-                       // correspondent GOT symbol.
-                       addgotsym(ctxt, targ)
-
-                       r.Sym = ctxt.Syms.Lookup(".got", 0)
-                       r.Add += int64(targ.Got())
-                       return true
-               }
-
-               // Process dynamic relocations for the data sections.
-               if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal {
-                       // When internally linking, generate dynamic relocations
-                       // for all typical R_ADDR relocations. The exception
-                       // are those R_ADDR that are created as part of generating
-                       // the dynamic relocations and must be resolved statically.
-                       //
-                       // There are three phases relevant to understanding this:
-                       //
-                       //      dodata()  // we are here
-                       //      address() // symbol address assignment
-                       //      reloc()   // resolution of static R_ADDR relocs
-                       //
-                       // At this point symbol addresses have not been
-                       // assigned yet (as the final size of the .rela section
-                       // will affect the addresses), and so we cannot write
-                       // the Elf64_Rela.r_offset now. Instead we delay it
-                       // until after the 'address' phase of the linker is
-                       // complete. We do this via Addaddrplus, which creates
-                       // a new R_ADDR relocation which will be resolved in
-                       // the 'reloc' phase.
-                       //
-                       // These synthetic static R_ADDR relocs must be skipped
-                       // now, or else we will be caught in an infinite loop
-                       // of generating synthetic relocs for our synthetic
-                       // relocs.
-                       //
-                       // Furthermore, the rela sections contain dynamic
-                       // relocations with R_ADDR relocations on
-                       // Elf64_Rela.r_offset. This field should contain the
-                       // symbol offset as determined by reloc(), not the
-                       // final dynamically linked address as a dynamic
-                       // relocation would provide.
-                       switch s.Name {
-                       case ".dynsym", ".rela", ".rela.plt", ".got.plt", ".dynamic":
-                               return false
-                       }
-               } else {
-                       // Either internally linking a static executable,
-                       // in which case we can resolve these relocations
-                       // statically in the 'reloc' phase, or externally
-                       // linking, in which case the relocation will be
-                       // prepared in the 'reloc' phase and passed to the
-                       // external linker in the 'asmb' phase.
-                       if s.Type != sym.SDATA && s.Type != sym.SRODATA {
-                               break
-                       }
-               }
-
-               if ctxt.IsELF {
-                       // Generate R_AARCH64_RELATIVE relocations for best
-                       // efficiency in the dynamic linker.
-                       //
-                       // As noted above, symbol addresses have not been
-                       // assigned yet, so we can't generate the final reloc
-                       // entry yet. We ultimately want:
-                       //
-                       // r_offset = s + r.Off
-                       // r_info = R_AARCH64_RELATIVE
-                       // r_addend = targ + r.Add
-                       //
-                       // The dynamic linker will set *offset = base address +
-                       // addend.
-                       //
-                       // AddAddrPlus is used for r_offset and r_addend to
-                       // generate new R_ADDR relocations that will update
-                       // these fields in the 'reloc' phase.
-                       rela := ctxt.Syms.Lookup(".rela", 0)
-                       rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
-                       if r.Siz == 8 {
-                               rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_AARCH64_RELATIVE)))
-                       } else {
-                               ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
-                       }
-                       rela.AddAddrPlus(ctxt.Arch, targ, int64(r.Add))
-                       // Not mark r done here. So we still apply it statically,
-                       // so in the file content we'll also have the right offset
-                       // to the relocation target. So it can be examined statically
-                       // (e.g. go version).
-                       return true
-               }
-       }
-       return false
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-       ctxt.Out.Write64(uint64(sectoff))
-
-       elfsym := r.Xsym.ElfsymForReloc()
-       switch r.Type {
-       default:
-               return false
-       case objabi.R_ADDR:
-               switch r.Siz {
-               case 4:
-                       ctxt.Out.Write64(uint64(elf.R_AARCH64_ABS32) | uint64(elfsym)<<32)
-               case 8:
-                       ctxt.Out.Write64(uint64(elf.R_AARCH64_ABS64) | uint64(elfsym)<<32)
-               default:
-                       return false
-               }
-       case objabi.R_ADDRARM64:
-               // two relocations: R_AARCH64_ADR_PREL_PG_HI21 and R_AARCH64_ADD_ABS_LO12_NC
-               ctxt.Out.Write64(uint64(elf.R_AARCH64_ADR_PREL_PG_HI21) | uint64(elfsym)<<32)
-               ctxt.Out.Write64(uint64(r.Xadd))
-               ctxt.Out.Write64(uint64(sectoff + 4))
-               ctxt.Out.Write64(uint64(elf.R_AARCH64_ADD_ABS_LO12_NC) | uint64(elfsym)<<32)
-       case objabi.R_ARM64_TLS_LE:
-               ctxt.Out.Write64(uint64(elf.R_AARCH64_TLSLE_MOVW_TPREL_G0) | uint64(elfsym)<<32)
-       case objabi.R_ARM64_TLS_IE:
-               ctxt.Out.Write64(uint64(elf.R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) | uint64(elfsym)<<32)
-               ctxt.Out.Write64(uint64(r.Xadd))
-               ctxt.Out.Write64(uint64(sectoff + 4))
-               ctxt.Out.Write64(uint64(elf.R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) | uint64(elfsym)<<32)
-       case objabi.R_ARM64_GOTPCREL:
-               ctxt.Out.Write64(uint64(elf.R_AARCH64_ADR_GOT_PAGE) | uint64(elfsym)<<32)
-               ctxt.Out.Write64(uint64(r.Xadd))
-               ctxt.Out.Write64(uint64(sectoff + 4))
-               ctxt.Out.Write64(uint64(elf.R_AARCH64_LD64_GOT_LO12_NC) | uint64(elfsym)<<32)
-       case objabi.R_CALLARM64:
-               if r.Siz != 4 {
-                       return false
-               }
-               ctxt.Out.Write64(uint64(elf.R_AARCH64_CALL26) | uint64(elfsym)<<32)
-
-       }
-       ctxt.Out.Write64(uint64(r.Xadd))
-
-       return true
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-       var v uint32
-
-       rs := r.Xsym
-
-       if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_CALLARM64 || r.Type == objabi.R_ADDRARM64 {
-               if rs.Dynid < 0 {
-                       ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
-                       return false
-               }
-
-               v = uint32(rs.Dynid)
-               v |= 1 << 27 // external relocation
-       } else {
-               v = uint32(rs.Sect.Extnum)
-               if v == 0 {
-                       ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
-                       return false
-               }
-       }
-
-       switch r.Type {
-       default:
-               return false
-       case objabi.R_ADDR:
-               v |= ld.MACHO_ARM64_RELOC_UNSIGNED << 28
-       case objabi.R_CALLARM64:
-               if r.Xadd != 0 {
-                       ld.Errorf(s, "ld64 doesn't allow BR26 reloc with non-zero addend: %s+%d", rs.Name, r.Xadd)
-               }
-
-               v |= 1 << 24 // pc-relative bit
-               v |= ld.MACHO_ARM64_RELOC_BRANCH26 << 28
-       case objabi.R_ADDRARM64:
-               r.Siz = 4
-               // Two relocation entries: MACHO_ARM64_RELOC_PAGEOFF12 MACHO_ARM64_RELOC_PAGE21
-               // if r.Xadd is non-zero, add two MACHO_ARM64_RELOC_ADDEND.
-               if r.Xadd != 0 {
-                       out.Write32(uint32(sectoff + 4))
-                       out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
-               }
-               out.Write32(uint32(sectoff + 4))
-               out.Write32(v | (ld.MACHO_ARM64_RELOC_PAGEOFF12 << 28) | (2 << 25))
-               if r.Xadd != 0 {
-                       out.Write32(uint32(sectoff))
-                       out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
-               }
-               v |= 1 << 24 // pc-relative bit
-               v |= ld.MACHO_ARM64_RELOC_PAGE21 << 28
-       }
-
-       switch r.Siz {
-       default:
-               return false
-       case 1:
-               v |= 0 << 25
-       case 2:
-               v |= 1 << 25
-       case 4:
-               v |= 2 << 25
-       case 8:
-               v |= 3 << 25
-       }
-
-       out.Write32(uint32(sectoff))
-       out.Write32(v)
-       return true
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-       if ctxt.LinkMode == ld.LinkExternal {
-               switch r.Type {
-               default:
-                       return val, false
-               case objabi.R_ARM64_GOTPCREL:
-                       var o1, o2 uint32
-                       if ctxt.Arch.ByteOrder == binary.BigEndian {
-                               o1 = uint32(val >> 32)
-                               o2 = uint32(val)
-                       } else {
-                               o1 = uint32(val)
-                               o2 = uint32(val >> 32)
-                       }
-                       // Any relocation against a function symbol is redirected to
-                       // be against a local symbol instead (see putelfsym in
-                       // symtab.go) but unfortunately the system linker was buggy
-                       // when confronted with a R_AARCH64_ADR_GOT_PAGE relocation
-                       // against a local symbol until May 2015
-                       // (https://sourceware.org/bugzilla/show_bug.cgi?id=18270). So
-                       // we convert the adrp; ld64 + R_ARM64_GOTPCREL into adrp;
-                       // add + R_ADDRARM64.
-                       if !(r.Sym.IsFileLocal() || r.Sym.Attr.VisibilityHidden() || r.Sym.Attr.Local()) && r.Sym.Type == sym.STEXT && ctxt.DynlinkingGo() {
-                               if o2&0xffc00000 != 0xf9400000 {
-                                       ld.Errorf(s, "R_ARM64_GOTPCREL against unexpected instruction %x", o2)
-                               }
-                               o2 = 0x91000000 | (o2 & 0x000003ff)
-                               r.Type = objabi.R_ADDRARM64
-                       }
-                       if ctxt.Arch.ByteOrder == binary.BigEndian {
-                               val = int64(o1)<<32 | int64(o2)
-                       } else {
-                               val = int64(o2)<<32 | int64(o1)
-                       }
-                       fallthrough
-               case objabi.R_ADDRARM64:
-                       r.Done = false
-
-                       // set up addend for eventual relocation via outer symbol.
-                       rs := r.Sym
-                       r.Xadd = r.Add
-                       for rs.Outer != nil {
-                               r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
-                               rs = rs.Outer
-                       }
-
-                       if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
-                               ld.Errorf(s, "missing section for %s", rs.Name)
-                       }
-                       r.Xsym = rs
-
-                       // Note: ld64 currently has a bug that any non-zero addend for BR26 relocation
-                       // will make the linking fail because it thinks the code is not PIC even though
-                       // the BR26 relocation should be fully resolved at link time.
-                       // That is the reason why the next if block is disabled. When the bug in ld64
-                       // is fixed, we can enable this block and also enable duff's device in cmd/7g.
-                       if false && ctxt.HeadType == objabi.Hdarwin {
-                               var o0, o1 uint32
-
-                               if ctxt.Arch.ByteOrder == binary.BigEndian {
-                                       o0 = uint32(val >> 32)
-                                       o1 = uint32(val)
-                               } else {
-                                       o0 = uint32(val)
-                                       o1 = uint32(val >> 32)
-                               }
-                               // Mach-O wants the addend to be encoded in the instruction
-                               // Note that although Mach-O supports ARM64_RELOC_ADDEND, it
-                               // can only encode 24-bit of signed addend, but the instructions
-                               // supports 33-bit of signed addend, so we always encode the
-                               // addend in place.
-                               o0 |= (uint32((r.Xadd>>12)&3) << 29) | (uint32((r.Xadd>>12>>2)&0x7ffff) << 5)
-                               o1 |= uint32(r.Xadd&0xfff) << 10
-                               r.Xadd = 0
-
-                               // when laid out, the instruction order must always be o1, o2.
-                               if ctxt.Arch.ByteOrder == binary.BigEndian {
-                                       val = int64(o0)<<32 | int64(o1)
-                               } else {
-                                       val = int64(o1)<<32 | int64(o0)
-                               }
-                       }
-
-                       return val, true
-               case objabi.R_CALLARM64,
-                       objabi.R_ARM64_TLS_LE,
-                       objabi.R_ARM64_TLS_IE:
-                       r.Done = false
-                       r.Xsym = r.Sym
-                       r.Xadd = r.Add
-                       return val, true
-               }
-       }
-
-       switch r.Type {
-       case objabi.R_CONST:
-               return r.Add, true
-
-       case objabi.R_GOTOFF:
-               return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
-
-       case objabi.R_ADDRARM64:
-               t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-               if t >= 1<<32 || t < -1<<32 {
-                       ld.Errorf(s, "program too large, address relocation distance = %d", t)
-               }
-
-               var o0, o1 uint32
-
-               if ctxt.Arch.ByteOrder == binary.BigEndian {
-                       o0 = uint32(val >> 32)
-                       o1 = uint32(val)
-               } else {
-                       o0 = uint32(val)
-                       o1 = uint32(val >> 32)
-               }
-
-               o0 |= (uint32((t>>12)&3) << 29) | (uint32((t>>12>>2)&0x7ffff) << 5)
-               o1 |= uint32(t&0xfff) << 10
-
-               // when laid out, the instruction order must always be o1, o2.
-               if ctxt.Arch.ByteOrder == binary.BigEndian {
-                       return int64(o0)<<32 | int64(o1), true
-               }
-               return int64(o1)<<32 | int64(o0), true
-
-       case objabi.R_ARM64_TLS_LE:
-               r.Done = false
-               if ctxt.HeadType == objabi.Hdarwin {
-                       ld.Errorf(s, "TLS reloc on unsupported OS %v", ctxt.HeadType)
-               }
-               // The TCB is two pointers. This is not documented anywhere, but is
-               // de facto part of the ABI.
-               v := r.Sym.Value + int64(2*ctxt.Arch.PtrSize)
-               if v < 0 || v >= 32678 {
-                       ld.Errorf(s, "TLS offset out of range %d", v)
-               }
-               return val | (v << 5), true
-
-       case objabi.R_ARM64_TLS_IE:
-               if ctxt.BuildMode == ld.BuildModePIE && ctxt.IsELF {
-                       // We are linking the final executable, so we
-                       // can optimize any TLS IE relocation to LE.
-                       r.Done = false
-                       if ctxt.HeadType != objabi.Hlinux {
-                               ld.Errorf(s, "TLS reloc on unsupported OS %v", ctxt.HeadType)
-                       }
-
-                       // The TCB is two pointers. This is not documented anywhere, but is
-                       // de facto part of the ABI.
-                       v := ld.Symaddr(r.Sym) + int64(2*ctxt.Arch.PtrSize) + r.Add
-                       if v < 0 || v >= 32678 {
-                               ld.Errorf(s, "TLS offset out of range %d", v)
-                       }
-
-                       var o0, o1 uint32
-                       if ctxt.Arch.ByteOrder == binary.BigEndian {
-                               o0 = uint32(val >> 32)
-                               o1 = uint32(val)
-                       } else {
-                               o0 = uint32(val)
-                               o1 = uint32(val >> 32)
-                       }
-
-                       // R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
-                       // turn ADRP to MOVZ
-                       o0 = 0xd2a00000 | uint32(o0&0x1f) | (uint32((v>>16)&0xffff) << 5)
-                       // R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
-                       // turn LD64 to MOVK
-                       if v&3 != 0 {
-                               ld.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC", v)
-                       }
-                       o1 = 0xf2800000 | uint32(o1&0x1f) | (uint32(v&0xffff) << 5)
-
-                       // when laid out, the instruction order must always be o0, o1.
-                       if ctxt.Arch.ByteOrder == binary.BigEndian {
-                               return int64(o0)<<32 | int64(o1), true
-                       }
-                       return int64(o1)<<32 | int64(o0), true
-               } else {
-                       log.Fatalf("cannot handle R_ARM64_TLS_IE (sym %s) when linking internally", s.Name)
-               }
-
-       case objabi.R_CALLARM64:
-               var t int64
-               if r.Sym.Type == sym.SDYNIMPORT {
-                       t = (ld.Symaddr(ctxt.Syms.Lookup(".plt", 0)) + r.Add) - (s.Value + int64(r.Off))
-               } else {
-                       t = (ld.Symaddr(r.Sym) + r.Add) - (s.Value + int64(r.Off))
-               }
-               if t >= 1<<27 || t < -1<<27 {
-                       ld.Errorf(s, "program too large, call relocation distance = %d", t)
-               }
-               return val | ((t >> 2) & 0x03ffffff), true
-
-       case objabi.R_ARM64_GOT:
-               if s.P[r.Off+3]&0x9f == 0x90 {
-                       // R_AARCH64_ADR_GOT_PAGE
-                       // patch instruction: adrp
-                       t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-                       if t >= 1<<32 || t < -1<<32 {
-                               ld.Errorf(s, "program too large, address relocation distance = %d", t)
-                       }
-                       var o0 uint32
-                       o0 |= (uint32((t>>12)&3) << 29) | (uint32((t>>12>>2)&0x7ffff) << 5)
-                       return val | int64(o0), true
-               } else if s.P[r.Off+3] == 0xf9 {
-                       // R_AARCH64_LD64_GOT_LO12_NC
-                       // patch instruction: ldr
-                       t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-                       if t&7 != 0 {
-                               ld.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_LD64_GOT_LO12_NC", t)
-                       }
-                       var o1 uint32
-                       o1 |= uint32(t&0xfff) << (10 - 3)
-                       return val | int64(uint64(o1)), true
-               } else {
-                       ld.Errorf(s, "unsupported instruction for %v R_GOTARM64", s.P[r.Off:r.Off+4])
-               }
-
-       case objabi.R_ARM64_PCREL:
-               if s.P[r.Off+3]&0x9f == 0x90 {
-                       // R_AARCH64_ADR_PREL_PG_HI21
-                       // patch instruction: adrp
-                       t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-                       if t >= 1<<32 || t < -1<<32 {
-                               ld.Errorf(s, "program too large, address relocation distance = %d", t)
-                       }
-                       o0 := (uint32((t>>12)&3) << 29) | (uint32((t>>12>>2)&0x7ffff) << 5)
-                       return val | int64(o0), true
-               } else if s.P[r.Off+3]&0x91 == 0x91 {
-                       // R_AARCH64_ADD_ABS_LO12_NC
-                       // patch instruction: add
-                       t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-                       o1 := uint32(t&0xfff) << 10
-                       return val | int64(o1), true
-               } else {
-                       ld.Errorf(s, "unsupported instruction for %v R_PCRELARM64", s.P[r.Off:r.Off+4])
-               }
-
-       case objabi.R_ARM64_LDST8:
-               t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-               o0 := uint32(t&0xfff) << 10
-               return val | int64(o0), true
-
-       case objabi.R_ARM64_LDST32:
-               t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-               if t&3 != 0 {
-                       ld.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_LDST32_ABS_LO12_NC", t)
-               }
-               o0 := (uint32(t&0xfff) >> 2) << 10
-               return val | int64(o0), true
-
-       case objabi.R_ARM64_LDST64:
-               t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-               if t&7 != 0 {
-                       ld.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_LDST64_ABS_LO12_NC", t)
-               }
-               o0 := (uint32(t&0xfff) >> 3) << 10
-               return val | int64(o0), true
-
-       case objabi.R_ARM64_LDST128:
-               t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
-               if t&15 != 0 {
-                       ld.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_LDST128_ABS_LO12_NC", t)
-               }
-               o0 := (uint32(t&0xfff) >> 4) << 10
-               return val | int64(o0), true
-       }
-
-       return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-       log.Fatalf("unexpected relocation variant")
-       return -1
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-       plt := ctxt.Syms.Lookup(".plt", 0)
-       gotplt := ctxt.Syms.Lookup(".got.plt", 0)
-       if plt.Size == 0 {
-               // stp     x16, x30, [sp, #-16]!
-               // identifying information
-               plt.AddUint32(ctxt.Arch, 0xa9bf7bf0)
-
-               // the following two instructions (adrp + ldr) load *got[2] into x17
-               // adrp    x16, &got[0]
-               plt.AddAddrPlus4(gotplt, 16)
-               plt.SetUint32(ctxt.Arch, plt.Size-4, 0x90000010)
-               plt.R[len(plt.R)-1].Type = objabi.R_ARM64_GOT
-
-               // <imm> is the offset value of &got[2] to &got[0], the same below
-               // ldr     x17, [x16, <imm>]
-               plt.AddAddrPlus4(gotplt, 16)
-               plt.SetUint32(ctxt.Arch, plt.Size-4, 0xf9400211)
-               plt.R[len(plt.R)-1].Type = objabi.R_ARM64_GOT
-
-               // add     x16, x16, <imm>
-               plt.AddAddrPlus4(gotplt, 16)
-               plt.SetUint32(ctxt.Arch, plt.Size-4, 0x91000210)
-               plt.R[len(plt.R)-1].Type = objabi.R_ARM64_PCREL
-
-               // br      x17
-               plt.AddUint32(ctxt.Arch, 0xd61f0220)
-
-               // 3 nop for place holder
-               plt.AddUint32(ctxt.Arch, 0xd503201f)
-               plt.AddUint32(ctxt.Arch, 0xd503201f)
-               plt.AddUint32(ctxt.Arch, 0xd503201f)
-
-               // check gotplt.size == 0
-               if gotplt.Size != 0 {
-                       ld.Errorf(gotplt, "got.plt is not empty at the very beginning")
-               }
-               gotplt.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
-
-               gotplt.AddUint64(ctxt.Arch, 0)
-               gotplt.AddUint64(ctxt.Arch, 0)
-       }
-}
-
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
-       if s.Plt() >= 0 {
-               return
-       }
-
-       ld.Adddynsym(ctxt, s)
-
-       if ctxt.IsELF {
-               plt := ctxt.Syms.Lookup(".plt", 0)
-               gotplt := ctxt.Syms.Lookup(".got.plt", 0)
-               rela := ctxt.Syms.Lookup(".rela.plt", 0)
-               if plt.Size == 0 {
-                       elfsetupplt(ctxt)
-               }
-
-               // adrp    x16, &got.plt[0]
-               plt.AddAddrPlus4(gotplt, gotplt.Size)
-               plt.SetUint32(ctxt.Arch, plt.Size-4, 0x90000010)
-               plt.R[len(plt.R)-1].Type = objabi.R_ARM64_GOT
-
-               // <offset> is the offset value of &got.plt[n] to &got.plt[0]
-               // ldr     x17, [x16, <offset>]
-               plt.AddAddrPlus4(gotplt, gotplt.Size)
-               plt.SetUint32(ctxt.Arch, plt.Size-4, 0xf9400211)
-               plt.R[len(plt.R)-1].Type = objabi.R_ARM64_GOT
-
-               // add     x16, x16, <offset>
-               plt.AddAddrPlus4(gotplt, gotplt.Size)
-               plt.SetUint32(ctxt.Arch, plt.Size-4, 0x91000210)
-               plt.R[len(plt.R)-1].Type = objabi.R_ARM64_PCREL
-
-               // br      x17
-               plt.AddUint32(ctxt.Arch, 0xd61f0220)
-
-               // add to got.plt: pointer to plt[0]
-               gotplt.AddAddrPlus(ctxt.Arch, plt, 0)
-
-               // rela
-               rela.AddAddrPlus(ctxt.Arch, gotplt, gotplt.Size-8)
-               rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_AARCH64_JUMP_SLOT)))
-               rela.AddUint64(ctxt.Arch, 0)
-
-               s.SetPlt(int32(plt.Size - 16))
-       } else {
-               ld.Errorf(s, "addpltsym: unsupported binary format")
-       }
-}
-
-func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
-       if s.Got() >= 0 {
-               return
-       }
-
-       ld.Adddynsym(ctxt, s)
-       got := ctxt.Syms.Lookup(".got", 0)
-       s.SetGot(int32(got.Size))
-       got.AddUint64(ctxt.Arch, 0)
-
-       if ctxt.IsELF {
-               rela := ctxt.Syms.Lookup(".rela", 0)
-               rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
-               rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_AARCH64_GLOB_DAT)))
-               rela.AddUint64(ctxt.Arch, 0)
-       } else {
-               ld.Errorf(s, "addgotsym: unsupported binary format")
-       }
-}
-
-func asmb(ctxt *ld.Link) {
-       if ctxt.IsELF {
-               ld.Asmbelfsetup()
-       }
-
-       sect := ld.Segtext.Sections[0]
-       ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-       ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-       for _, sect = range ld.Segtext.Sections[1:] {
-               ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-               ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-       }
-
-       if ld.Segrodata.Filelen > 0 {
-               ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-               ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-       }
-       if ld.Segrelrodata.Filelen > 0 {
-               ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
-               ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
-       }
-
-       ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-       ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-       ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-       ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-       machlink := uint32(0)
-       if ctxt.HeadType == objabi.Hdarwin {
-               machlink = uint32(ld.Domacholink(ctxt))
-       }
-
-       /* output symbol table */
-       ld.Symsize = 0
-
-       ld.Lcsize = 0
-       symo := uint32(0)
-       if !*ld.FlagS {
-               // TODO: rationalize
-               switch ctxt.HeadType {
-               default:
-                       if ctxt.IsELF {
-                               symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-                               symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
-                       }
-
-               case objabi.Hplan9:
-                       symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
-
-               case objabi.Hdarwin:
-                       symo = uint32(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(*ld.FlagRound))) + uint64(machlink))
-               }
-
-               ctxt.Out.SeekSet(int64(symo))
-               switch ctxt.HeadType {
-               default:
-                       if ctxt.IsELF {
-                               ld.Asmelfsym(ctxt)
-                               ctxt.Out.Flush()
-                               ctxt.Out.Write(ld.Elfstrdat)
-
-                               if ctxt.LinkMode == ld.LinkExternal {
-                                       ld.Elfemitreloc(ctxt)
-                               }
-                       }
-
-               case objabi.Hplan9:
-                       ld.Asmplan9sym(ctxt)
-                       ctxt.Out.Flush()
-
-                       sym := ctxt.Syms.Lookup("pclntab", 0)
-                       if sym != nil {
-                               ld.Lcsize = int32(len(sym.P))
-                               ctxt.Out.Write(sym.P)
-                               ctxt.Out.Flush()
-                       }
-
-               case objabi.Hdarwin:
-                       if ctxt.LinkMode == ld.LinkExternal {
-                               ld.Machoemitreloc(ctxt)
-                       }
-               }
-       }
-
-       ctxt.Out.SeekSet(0)
-       switch ctxt.HeadType {
-       default:
-       case objabi.Hplan9: /* plan 9 */
-               ctxt.Out.Write32(0x647)                      /* magic */
-               ctxt.Out.Write32(uint32(ld.Segtext.Filelen)) /* sizes */
-               ctxt.Out.Write32(uint32(ld.Segdata.Filelen))
-               ctxt.Out.Write32(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-               ctxt.Out.Write32(uint32(ld.Symsize))          /* nsyms */
-               ctxt.Out.Write32(uint32(ld.Entryvalue(ctxt))) /* va of entry */
-               ctxt.Out.Write32(0)
-               ctxt.Out.Write32(uint32(ld.Lcsize))
-
-       case objabi.Hlinux,
-               objabi.Hfreebsd,
-               objabi.Hnetbsd,
-               objabi.Hopenbsd:
-               ld.Asmbelf(ctxt, int64(symo))
-
-       case objabi.Hdarwin:
-               ld.Asmbmacho(ctxt)
-       }
-
-       ctxt.Out.Flush()
-       if *ld.FlagC {
-               fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
-               fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
-               fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
-               fmt.Printf("symsize=%d\n", ld.Symsize)
-               fmt.Printf("lcsize=%d\n", ld.Lcsize)
-               fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
-       }
-}
diff --git a/src/cmd/oldlink/internal/arm64/l.go b/src/cmd/oldlink/internal/arm64/l.go
deleted file mode 100644 (file)
index 5f35303..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package arm64
-
-// Writing object files.
-
-// cmd/9l/l.h from Vita Nuova.
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-const (
-       maxAlign  = 32 // max data alignment
-       minAlign  = 1  // min data alignment
-       funcAlign = 16
-)
-
-/* Used by ../internal/ld/dwarf.go */
-const (
-       dwarfRegSP = 31
-       dwarfRegLR = 30
-)
diff --git a/src/cmd/oldlink/internal/arm64/obj.go b/src/cmd/oldlink/internal/arm64/obj.go
deleted file mode 100644 (file)
index 2dcc999..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-// Inferno utils/5l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/obj.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package arm64
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-       arch := sys.ArchARM64
-
-       theArch := ld.Arch{
-               Funcalign:  funcAlign,
-               Maxalign:   maxAlign,
-               Minalign:   minAlign,
-               Dwarfregsp: dwarfRegSP,
-               Dwarfreglr: dwarfRegLR,
-
-               Adddynrel:        adddynrel,
-               Archinit:         archinit,
-               Archreloc:        archreloc,
-               Archrelocvariant: archrelocvariant,
-               Asmb:             asmb,
-               Asmb2:            asmb2,
-               Elfreloc1:        elfreloc1,
-               Elfsetupplt:      elfsetupplt,
-               Gentext:          gentext,
-               Machoreloc1:      machoreloc1,
-
-               Androiddynld: "/system/bin/linker64",
-               Linuxdynld:   "/lib/ld-linux-aarch64.so.1",
-
-               Freebsddynld:   "/usr/libexec/ld-elf.so.1",
-               Openbsddynld:   "/usr/libexec/ld.so",
-               Netbsddynld:    "/libexec/ld.elf_so",
-               Dragonflydynld: "XXX",
-               Solarisdynld:   "XXX",
-       }
-
-       return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-       switch ctxt.HeadType {
-       default:
-               ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-
-       case objabi.Hplan9: /* plan 9 */
-               ld.HEADR = 32
-
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = 4096 + int64(ld.HEADR)
-               }
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 4096
-               }
-
-       case objabi.Hlinux, /* arm64 elf */
-               objabi.Hfreebsd,
-               objabi.Hnetbsd,
-               objabi.Hopenbsd:
-               ld.Elfinit(ctxt)
-               ld.HEADR = ld.ELFRESERVE
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
-               }
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 0x10000
-               }
-
-       case objabi.Hdarwin: /* apple MACH */
-               ld.HEADR = ld.INITIAL_MACHO_HEADR
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = 4096 + int64(ld.HEADR)
-               }
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 4096
-               }
-       }
-}
diff --git a/src/cmd/oldlink/internal/ld/ar.go b/src/cmd/oldlink/internal/ld/ar.go
deleted file mode 100644 (file)
index 8df859f..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-// Inferno utils/include/ar.h
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/include/ar.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ld
-
-import (
-       "cmd/internal/bio"
-       "cmd/internal/objabi"
-       "cmd/oldlink/internal/sym"
-       "encoding/binary"
-       "fmt"
-       "io"
-       "os"
-)
-
-const (
-       SARMAG  = 8
-       SAR_HDR = 16 + 44
-)
-
-const (
-       ARMAG = "!<arch>\n"
-)
-
-type ArHdr struct {
-       name string
-       date string
-       uid  string
-       gid  string
-       mode string
-       size string
-       fmag string
-}
-
-// hostArchive reads an archive file holding host objects and links in
-// required objects. The general format is the same as a Go archive
-// file, but it has an armap listing symbols and the objects that
-// define them. This is used for the compiler support library
-// libgcc.a.
-func hostArchive(ctxt *Link, name string) {
-       f, err := bio.Open(name)
-       if err != nil {
-               if os.IsNotExist(err) {
-                       // It's OK if we don't have a libgcc file at all.
-                       if ctxt.Debugvlog != 0 {
-                               ctxt.Logf("skipping libgcc file: %v\n", err)
-                       }
-                       return
-               }
-               Exitf("cannot open file %s: %v", name, err)
-       }
-       defer f.Close()
-
-       var magbuf [len(ARMAG)]byte
-       if _, err := io.ReadFull(f, magbuf[:]); err != nil {
-               Exitf("file %s too short", name)
-       }
-
-       if string(magbuf[:]) != ARMAG {
-               Exitf("%s is not an archive file", name)
-       }
-
-       var arhdr ArHdr
-       l := nextar(f, f.Offset(), &arhdr)
-       if l <= 0 {
-               Exitf("%s missing armap", name)
-       }
-
-       var armap archiveMap
-       if arhdr.name == "/" || arhdr.name == "/SYM64/" {
-               armap = readArmap(name, f, arhdr)
-       } else {
-               Exitf("%s missing armap", name)
-       }
-
-       loaded := make(map[uint64]bool)
-       any := true
-       for any {
-               var load []uint64
-               for _, s := range ctxt.Syms.Allsym {
-                       for i := range s.R {
-                               r := &s.R[i] // Copying sym.Reloc has measurable impact on performance
-                               if r.Sym != nil && r.Sym.Type == sym.SXREF {
-                                       if off := armap[r.Sym.Name]; off != 0 && !loaded[off] {
-                                               load = append(load, off)
-                                               loaded[off] = true
-                                       }
-                               }
-                       }
-               }
-
-               for _, off := range load {
-                       l := nextar(f, int64(off), &arhdr)
-                       if l <= 0 {
-                               Exitf("%s missing archive entry at offset %d", name, off)
-                       }
-                       pname := fmt.Sprintf("%s(%s)", name, arhdr.name)
-                       l = atolwhex(arhdr.size)
-
-                       libgcc := sym.Library{Pkg: "libgcc"}
-                       h := ldobj(ctxt, f, &libgcc, l, pname, name)
-                       f.MustSeek(h.off, 0)
-                       h.ld(ctxt, f, h.pkg, h.length, h.pn)
-               }
-
-               any = len(load) > 0
-       }
-}
-
-// archiveMap is an archive symbol map: a mapping from symbol name to
-// offset within the archive file.
-type archiveMap map[string]uint64
-
-// readArmap reads the archive symbol map.
-func readArmap(filename string, f *bio.Reader, arhdr ArHdr) archiveMap {
-       is64 := arhdr.name == "/SYM64/"
-       wordSize := 4
-       if is64 {
-               wordSize = 8
-       }
-
-       contents := make([]byte, atolwhex(arhdr.size))
-       if _, err := io.ReadFull(f, contents); err != nil {
-               Exitf("short read from %s", filename)
-       }
-
-       var c uint64
-       if is64 {
-               c = binary.BigEndian.Uint64(contents)
-       } else {
-               c = uint64(binary.BigEndian.Uint32(contents))
-       }
-       contents = contents[wordSize:]
-
-       ret := make(archiveMap)
-
-       names := contents[c*uint64(wordSize):]
-       for i := uint64(0); i < c; i++ {
-               n := 0
-               for names[n] != 0 {
-                       n++
-               }
-               name := string(names[:n])
-               names = names[n+1:]
-
-               // For Mach-O and PE/386 files we strip a leading
-               // underscore from the symbol name.
-               if objabi.GOOS == "darwin" || (objabi.GOOS == "windows" && objabi.GOARCH == "386") {
-                       if name[0] == '_' && len(name) > 1 {
-                               name = name[1:]
-                       }
-               }
-
-               var off uint64
-               if is64 {
-                       off = binary.BigEndian.Uint64(contents)
-               } else {
-                       off = uint64(binary.BigEndian.Uint32(contents))
-               }
-               contents = contents[wordSize:]
-
-               ret[name] = off
-       }
-
-       return ret
-}
diff --git a/src/cmd/oldlink/internal/ld/config.go b/src/cmd/oldlink/internal/ld/config.go
deleted file mode 100644 (file)
index 2373b50..0000000
+++ /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 (file)
index ba4a741..0000000
+++ /dev/null
@@ -1,2501 +0,0 @@
-// Derived from Inferno utils/6l/obj.c and utils/6l/span.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ld
-
-import (
-       "bufio"
-       "bytes"
-       "cmd/internal/gcprog"
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/sym"
-       "compress/zlib"
-       "encoding/binary"
-       "fmt"
-       "log"
-       "os"
-       "sort"
-       "strconv"
-       "strings"
-       "sync"
-)
-
-// isRuntimeDepPkg reports whether pkg is the runtime package or its dependency
-func isRuntimeDepPkg(pkg string) bool {
-       switch pkg {
-       case "runtime",
-               "sync/atomic",      // runtime may call to sync/atomic, due to go:linkname
-               "internal/bytealg", // for IndexByte
-               "internal/cpu":     // for cpu features
-               return true
-       }
-       return strings.HasPrefix(pkg, "runtime/internal/") && !strings.HasSuffix(pkg, "_test")
-}
-
-// Estimate the max size needed to hold any new trampolines created for this function. This
-// is used to determine when the section can be split if it becomes too large, to ensure that
-// the trampolines are in the same section as the function that uses them.
-func maxSizeTrampolinesPPC64(s *sym.Symbol, isTramp bool) uint64 {
-       // If thearch.Trampoline is nil, then trampoline support is not available on this arch.
-       // A trampoline does not need any dependent trampolines.
-       if thearch.Trampoline == nil || isTramp {
-               return 0
-       }
-
-       n := uint64(0)
-       for ri := range s.R {
-               r := &s.R[ri]
-               if r.Type.IsDirectCallOrJump() {
-                       n++
-               }
-       }
-       // Trampolines in ppc64 are 4 instructions.
-       return n * 16
-}
-
-// detect too-far jumps in function s, and add trampolines if necessary
-// ARM, PPC64 & PPC64LE support trampoline insertion for internal and external linking
-// On PPC64 & PPC64LE the text sections might be split but will still insert trampolines
-// where necessary.
-func trampoline(ctxt *Link, s *sym.Symbol) {
-       if thearch.Trampoline == nil {
-               return // no need or no support of trampolines on this arch
-       }
-
-       for ri := range s.R {
-               r := &s.R[ri]
-               if !r.Type.IsDirectCallOrJump() {
-                       continue
-               }
-               if Symaddr(r.Sym) == 0 && (r.Sym.Type != sym.SDYNIMPORT && r.Sym.Type != sym.SUNDEFEXT) {
-                       if r.Sym.File != s.File {
-                               if !isRuntimeDepPkg(s.File) || !isRuntimeDepPkg(r.Sym.File) {
-                                       ctxt.ErrorUnresolved(s, r)
-                               }
-                               // runtime and its dependent packages may call to each other.
-                               // they are fine, as they will be laid down together.
-                       }
-                       continue
-               }
-
-               thearch.Trampoline(ctxt, r, s)
-       }
-
-}
-
-// relocsym resolve relocations in "s". The main loop walks through
-// the list of relocations attached to "s" and resolves them where
-// applicable. Relocations are often architecture-specific, requiring
-// calls into the 'archreloc' and/or 'archrelocvariant' functions for
-// the architecture. When external linking is in effect, it may not be
-// possible to completely resolve the address/offset for a symbol, in
-// which case the goal is to lay the groundwork for turning a given
-// relocation into an external reloc (to be applied by the external
-// linker). For more on how relocations work in general, see
-//
-//  "Linkers and Loaders", by John R. Levine (Morgan Kaufmann, 1999), ch. 7
-//
-// This is a performance-critical function for the linker; be careful
-// to avoid introducing unnecessary allocations in the main loop.
-func relocsym(ctxt *Link, s *sym.Symbol) {
-       if len(s.R) == 0 {
-               return
-       }
-       if s.Attr.ReadOnly() {
-               // The symbol's content is backed by read-only memory.
-               // Copy it to writable memory to apply relocations.
-               s.P = append([]byte(nil), s.P...)
-               s.Attr.Set(sym.AttrReadOnly, false)
-       }
-       for ri := int32(0); ri < int32(len(s.R)); ri++ {
-               r := &s.R[ri]
-               if r.Done {
-                       // Relocation already processed by an earlier phase.
-                       continue
-               }
-               r.Done = true
-               off := r.Off
-               siz := int32(r.Siz)
-               if off < 0 || off+siz > int32(len(s.P)) {
-                       rname := ""
-                       if r.Sym != nil {
-                               rname = r.Sym.Name
-                       }
-                       Errorf(s, "invalid relocation %s: %d+%d not in [%d,%d)", rname, off, siz, 0, len(s.P))
-                       continue
-               }
-
-               if r.Sym != nil && ((r.Sym.Type == sym.Sxxx && !r.Sym.Attr.VisibilityHidden()) || r.Sym.Type == sym.SXREF) {
-                       // When putting the runtime but not main into a shared library
-                       // these symbols are undefined and that's OK.
-                       if ctxt.BuildMode == BuildModeShared || ctxt.BuildMode == BuildModePlugin {
-                               if r.Sym.Name == "main.main" || (ctxt.BuildMode != BuildModePlugin && r.Sym.Name == "main..inittask") {
-                                       r.Sym.Type = sym.SDYNIMPORT
-                               } else if strings.HasPrefix(r.Sym.Name, "go.info.") {
-                                       // Skip go.info symbols. They are only needed to communicate
-                                       // DWARF info between the compiler and linker.
-                                       continue
-                               }
-                       } else {
-                               ctxt.ErrorUnresolved(s, r)
-                               continue
-                       }
-               }
-
-               if r.Type >= objabi.ElfRelocOffset {
-                       continue
-               }
-               if r.Siz == 0 { // informational relocation - no work to do
-                       continue
-               }
-
-               // We need to be able to reference dynimport symbols when linking against
-               // shared libraries, and Solaris, Darwin and AIX need it always
-               if ctxt.HeadType != objabi.Hsolaris && ctxt.HeadType != objabi.Hdarwin && ctxt.HeadType != objabi.Haix && r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT && !ctxt.DynlinkingGo() && !r.Sym.Attr.SubSymbol() {
-                       if !(ctxt.Arch.Family == sys.PPC64 && ctxt.LinkMode == LinkExternal && r.Sym.Name == ".TOC.") {
-                               Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", r.Sym.Name, r.Sym.Type, r.Sym.Type, r.Type, sym.RelocName(ctxt.Arch, r.Type))
-                       }
-               }
-               if r.Sym != nil && r.Sym.Type != sym.STLSBSS && r.Type != objabi.R_WEAKADDROFF && !r.Sym.Attr.Reachable() {
-                       Errorf(s, "unreachable sym in relocation: %s", r.Sym.Name)
-               }
-
-               if ctxt.LinkMode == LinkExternal {
-                       r.InitExt()
-               }
-
-               // TODO(mundaym): remove this special case - see issue 14218.
-               if ctxt.Arch.Family == sys.S390X {
-                       switch r.Type {
-                       case objabi.R_PCRELDBL:
-                               r.InitExt()
-                               r.Type = objabi.R_PCREL
-                               r.Variant = sym.RV_390_DBL
-                       case objabi.R_CALL:
-                               r.InitExt()
-                               r.Variant = sym.RV_390_DBL
-                       }
-               }
-
-               var o int64
-               switch r.Type {
-               default:
-                       switch siz {
-                       default:
-                               Errorf(s, "bad reloc size %#x for %s", uint32(siz), r.Sym.Name)
-                       case 1:
-                               o = int64(s.P[off])
-                       case 2:
-                               o = int64(ctxt.Arch.ByteOrder.Uint16(s.P[off:]))
-                       case 4:
-                               o = int64(ctxt.Arch.ByteOrder.Uint32(s.P[off:]))
-                       case 8:
-                               o = int64(ctxt.Arch.ByteOrder.Uint64(s.P[off:]))
-                       }
-                       if offset, ok := thearch.Archreloc(ctxt, r, s, o); ok {
-                               o = offset
-                       } else {
-                               Errorf(s, "unknown reloc to %v: %d (%s)", r.Sym.Name, r.Type, sym.RelocName(ctxt.Arch, r.Type))
-                       }
-               case objabi.R_TLS_LE:
-                       if ctxt.LinkMode == LinkExternal && ctxt.IsELF {
-                               r.Done = false
-                               if r.Sym == nil {
-                                       r.Sym = ctxt.Tlsg
-                               }
-                               r.Xsym = r.Sym
-                               r.Xadd = r.Add
-                               o = 0
-                               if ctxt.Arch.Family != sys.AMD64 {
-                                       o = r.Add
-                               }
-                               break
-                       }
-
-                       if ctxt.IsELF && ctxt.Arch.Family == sys.ARM {
-                               // On ELF ARM, the thread pointer is 8 bytes before
-                               // the start of the thread-local data block, so add 8
-                               // to the actual TLS offset (r->sym->value).
-                               // This 8 seems to be a fundamental constant of
-                               // ELF on ARM (or maybe Glibc on ARM); it is not
-                               // related to the fact that our own TLS storage happens
-                               // to take up 8 bytes.
-                               o = 8 + r.Sym.Value
-                       } else if ctxt.IsELF || ctxt.HeadType == objabi.Hplan9 || ctxt.HeadType == objabi.Hdarwin {
-                               o = int64(ctxt.Tlsoffset) + r.Add
-                       } else if ctxt.HeadType == objabi.Hwindows {
-                               o = r.Add
-                       } else {
-                               log.Fatalf("unexpected R_TLS_LE relocation for %v", ctxt.HeadType)
-                       }
-               case objabi.R_TLS_IE:
-                       if ctxt.LinkMode == LinkExternal && ctxt.IsELF {
-                               r.Done = false
-                               if r.Sym == nil {
-                                       r.Sym = ctxt.Tlsg
-                               }
-                               r.Xsym = r.Sym
-                               r.Xadd = r.Add
-                               o = 0
-                               if ctxt.Arch.Family != sys.AMD64 {
-                                       o = r.Add
-                               }
-                               break
-                       }
-                       if ctxt.BuildMode == BuildModePIE && ctxt.IsELF {
-                               // We are linking the final executable, so we
-                               // can optimize any TLS IE relocation to LE.
-                               if thearch.TLSIEtoLE == nil {
-                                       log.Fatalf("internal linking of TLS IE not supported on %v", ctxt.Arch.Family)
-                               }
-                               thearch.TLSIEtoLE(s, int(off), int(r.Siz))
-                               o = int64(ctxt.Tlsoffset)
-                               // TODO: o += r.Add when ctxt.Arch.Family != sys.AMD64?
-                               // Why do we treat r.Add differently on AMD64?
-                               // Is the external linker using Xadd at all?
-                       } else {
-                               log.Fatalf("cannot handle R_TLS_IE (sym %s) when linking internally", s.Name)
-                       }
-               case objabi.R_ADDR:
-                       if ctxt.LinkMode == LinkExternal && r.Sym.Type != sym.SCONST {
-                               r.Done = false
-
-                               // set up addend for eventual relocation via outer symbol.
-                               rs := r.Sym
-
-                               r.Xadd = r.Add
-                               for rs.Outer != nil {
-                                       r.Xadd += Symaddr(rs) - Symaddr(rs.Outer)
-                                       rs = rs.Outer
-                               }
-
-                               if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Type != sym.SUNDEFEXT && rs.Sect == nil {
-                                       Errorf(s, "missing section for relocation target %s", rs.Name)
-                               }
-                               r.Xsym = rs
-
-                               o = r.Xadd
-                               if ctxt.IsELF {
-                                       if ctxt.Arch.Family == sys.AMD64 {
-                                               o = 0
-                                       }
-                               } else if ctxt.HeadType == objabi.Hdarwin {
-                                       if rs.Type != sym.SHOSTOBJ {
-                                               o += Symaddr(rs)
-                                       }
-                               } else if ctxt.HeadType == objabi.Hwindows {
-                                       // nothing to do
-                               } else if ctxt.HeadType == objabi.Haix {
-                                       o = Symaddr(r.Sym) + r.Add
-                               } else {
-                                       Errorf(s, "unhandled pcrel relocation to %s on %v", rs.Name, ctxt.HeadType)
-                               }
-
-                               break
-                       }
-
-                       // On AIX, a second relocation must be done by the loader,
-                       // as section addresses can change once loaded.
-                       // The "default" symbol address is still needed by the loader so
-                       // the current relocation can't be skipped.
-                       if ctxt.HeadType == objabi.Haix && r.Sym.Type != sym.SDYNIMPORT {
-                               // It's not possible to make a loader relocation in a
-                               // symbol which is not inside .data section.
-                               // FIXME: It should be forbidden to have R_ADDR from a
-                               // symbol which isn't in .data. However, as .text has the
-                               // same address once loaded, this is possible.
-                               if s.Sect.Seg == &Segdata {
-                                       Xcoffadddynrel(ctxt, s, r)
-                               }
-                       }
-
-                       o = Symaddr(r.Sym) + r.Add
-
-                       // On amd64, 4-byte offsets will be sign-extended, so it is impossible to
-                       // access more than 2GB of static data; fail at link time is better than
-                       // fail at runtime. See https://golang.org/issue/7980.
-                       // Instead of special casing only amd64, we treat this as an error on all
-                       // 64-bit architectures so as to be future-proof.
-                       if int32(o) < 0 && ctxt.Arch.PtrSize > 4 && siz == 4 {
-                               Errorf(s, "non-pc-relative relocation address for %s is too big: %#x (%#x + %#x)", r.Sym.Name, uint64(o), Symaddr(r.Sym), r.Add)
-                               errorexit()
-                       }
-               case objabi.R_DWARFSECREF:
-                       if r.Sym.Sect == nil {
-                               Errorf(s, "missing DWARF section for relocation target %s", r.Sym.Name)
-                       }
-
-                       if ctxt.LinkMode == LinkExternal {
-                               r.Done = false
-
-                               // On most platforms, the external linker needs to adjust DWARF references
-                               // as it combines DWARF sections. However, on Darwin, dsymutil does the
-                               // DWARF linking, and it understands how to follow section offsets.
-                               // Leaving in the relocation records confuses it (see
-                               // https://golang.org/issue/22068) so drop them for Darwin.
-                               if ctxt.HeadType == objabi.Hdarwin {
-                                       r.Done = true
-                               }
-
-                               // PE code emits IMAGE_REL_I386_SECREL and IMAGE_REL_AMD64_SECREL
-                               // for R_DWARFSECREF relocations, while R_ADDR is replaced with
-                               // IMAGE_REL_I386_DIR32, IMAGE_REL_AMD64_ADDR64 and IMAGE_REL_AMD64_ADDR32.
-                               // Do not replace R_DWARFSECREF with R_ADDR for windows -
-                               // let PE code emit correct relocations.
-                               if ctxt.HeadType != objabi.Hwindows {
-                                       r.Type = objabi.R_ADDR
-                               }
-
-                               r.Xsym = ctxt.Syms.ROLookup(r.Sym.Sect.Name, 0)
-                               r.Xadd = r.Add + Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr)
-
-                               o = r.Xadd
-                               if ctxt.IsELF && ctxt.Arch.Family == sys.AMD64 {
-                                       o = 0
-                               }
-                               break
-                       }
-                       o = Symaddr(r.Sym) + r.Add - int64(r.Sym.Sect.Vaddr)
-               case objabi.R_WEAKADDROFF:
-                       if !r.Sym.Attr.Reachable() {
-                               continue
-                       }
-                       fallthrough
-               case objabi.R_ADDROFF:
-                       // The method offset tables using this relocation expect the offset to be relative
-                       // to the start of the first text section, even if there are multiple.
-                       if r.Sym.Sect.Name == ".text" {
-                               o = Symaddr(r.Sym) - int64(Segtext.Sections[0].Vaddr) + r.Add
-                       } else {
-                               o = Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr) + r.Add
-                       }
-
-               case objabi.R_ADDRCUOFF:
-                       // debug_range and debug_loc elements use this relocation type to get an
-                       // offset from the start of the compile unit.
-                       o = Symaddr(r.Sym) + r.Add - Symaddr(r.Sym.Unit.Textp[0])
-
-                       // r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call.
-               case objabi.R_GOTPCREL:
-                       if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin && r.Sym != nil && r.Sym.Type != sym.SCONST {
-                               r.Done = false
-                               r.Xadd = r.Add
-                               r.Xadd -= int64(r.Siz) // relative to address after the relocated chunk
-                               r.Xsym = r.Sym
-
-                               o = r.Xadd
-                               o += int64(r.Siz)
-                               break
-                       }
-                       fallthrough
-               case objabi.R_CALL, objabi.R_PCREL:
-                       if ctxt.LinkMode == LinkExternal && r.Sym != nil && r.Sym.Type == sym.SUNDEFEXT {
-                               // pass through to the external linker.
-                               r.Done = false
-                               r.Xadd = 0
-                               if ctxt.IsELF {
-                                       r.Xadd -= int64(r.Siz)
-                               }
-                               r.Xsym = r.Sym
-                               o = 0
-                               break
-                       }
-                       if ctxt.LinkMode == LinkExternal && r.Sym != nil && r.Sym.Type != sym.SCONST && (r.Sym.Sect != s.Sect || r.Type == objabi.R_GOTPCREL) {
-                               r.Done = false
-
-                               // set up addend for eventual relocation via outer symbol.
-                               rs := r.Sym
-
-                               r.Xadd = r.Add
-                               for rs.Outer != nil {
-                                       r.Xadd += Symaddr(rs) - Symaddr(rs.Outer)
-                                       rs = rs.Outer
-                               }
-
-                               r.Xadd -= int64(r.Siz) // relative to address after the relocated chunk
-                               if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
-                                       Errorf(s, "missing section for relocation target %s", rs.Name)
-                               }
-                               r.Xsym = rs
-
-                               o = r.Xadd
-                               if ctxt.IsELF {
-                                       if ctxt.Arch.Family == sys.AMD64 {
-                                               o = 0
-                                       }
-                               } else if ctxt.HeadType == objabi.Hdarwin {
-                                       if r.Type == objabi.R_CALL {
-                                               if ctxt.LinkMode == LinkExternal && rs.Type == sym.SDYNIMPORT {
-                                                       if ctxt.Arch.Family == sys.AMD64 {
-                                                               // AMD64 dynamic relocations are relative to the end of the relocation.
-                                                               o += int64(r.Siz)
-                                                       }
-                                               } else {
-                                                       if rs.Type != sym.SHOSTOBJ {
-                                                               o += int64(uint64(Symaddr(rs)) - rs.Sect.Vaddr)
-                                                       }
-                                                       o -= int64(r.Off) // relative to section offset, not symbol
-                                               }
-                                       } else {
-                                               o += int64(r.Siz)
-                                       }
-                               } else if ctxt.HeadType == objabi.Hwindows && ctxt.Arch.Family == sys.AMD64 { // only amd64 needs PCREL
-                                       // PE/COFF's PC32 relocation uses the address after the relocated
-                                       // bytes as the base. Compensate by skewing the addend.
-                                       o += int64(r.Siz)
-                               } else {
-                                       Errorf(s, "unhandled pcrel relocation to %s on %v", rs.Name, ctxt.HeadType)
-                               }
-
-                               break
-                       }
-
-                       o = 0
-                       if r.Sym != nil {
-                               o += Symaddr(r.Sym)
-                       }
-
-                       o += r.Add - (s.Value + int64(r.Off) + int64(r.Siz))
-               case objabi.R_SIZE:
-                       o = r.Sym.Size + r.Add
-
-               case objabi.R_XCOFFREF:
-                       if ctxt.HeadType != objabi.Haix {
-                               Errorf(s, "find XCOFF R_REF on non-XCOFF files")
-                       }
-                       if ctxt.LinkMode != LinkExternal {
-                               Errorf(s, "find XCOFF R_REF with internal linking")
-                       }
-                       r.Xsym = r.Sym
-                       r.Xadd = r.Add
-                       r.Done = false
-
-                       // This isn't a real relocation so it must not update
-                       // its offset value.
-                       continue
-
-               case objabi.R_DWARFFILEREF:
-                       // The final file index is saved in r.Add in dwarf.go:writelines.
-                       o = r.Add
-               }
-
-               if ctxt.Arch.Family == sys.PPC64 || ctxt.Arch.Family == sys.S390X {
-                       r.InitExt()
-                       if r.Variant != sym.RV_NONE {
-                               o = thearch.Archrelocvariant(ctxt, r, s, o)
-                       }
-               }
-
-               if false {
-                       nam := "<nil>"
-                       var addr int64
-                       if r.Sym != nil {
-                               nam = r.Sym.Name
-                               addr = Symaddr(r.Sym)
-                       }
-                       xnam := "<nil>"
-                       if r.Xsym != nil {
-                               xnam = r.Xsym.Name
-                       }
-                       fmt.Printf("relocate %s %#x (%#x+%#x, size %d) => %s %#x +%#x (xsym: %s +%#x) [type %d (%s)/%d, %x]\n", s.Name, s.Value+int64(off), s.Value, r.Off, r.Siz, nam, addr, r.Add, xnam, r.Xadd, r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Variant, o)
-               }
-               switch siz {
-               default:
-                       Errorf(s, "bad reloc size %#x for %s", uint32(siz), r.Sym.Name)
-                       fallthrough
-
-                       // TODO(rsc): Remove.
-               case 1:
-                       s.P[off] = byte(int8(o))
-               case 2:
-                       if o != int64(int16(o)) {
-                               Errorf(s, "relocation address for %s is too big: %#x", r.Sym.Name, o)
-                       }
-                       i16 := int16(o)
-                       ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(i16))
-               case 4:
-                       if r.Type == objabi.R_PCREL || r.Type == objabi.R_CALL {
-                               if o != int64(int32(o)) {
-                                       Errorf(s, "pc-relative relocation address for %s is too big: %#x", r.Sym.Name, o)
-                               }
-                       } else {
-                               if o != int64(int32(o)) && o != int64(uint32(o)) {
-                                       Errorf(s, "non-pc-relative relocation address for %s is too big: %#x", r.Sym.Name, uint64(o))
-                               }
-                       }
-
-                       fl := int32(o)
-                       ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(fl))
-               case 8:
-                       ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(o))
-               }
-       }
-}
-
-func (ctxt *Link) reloc() {
-       for _, s := range ctxt.Textp {
-               relocsym(ctxt, s)
-       }
-       for _, s := range datap {
-               relocsym(ctxt, s)
-       }
-       for _, s := range dwarfp {
-               relocsym(ctxt, s)
-       }
-}
-
-func windynrelocsym(ctxt *Link, rel, s *sym.Symbol) {
-       for ri := range s.R {
-               r := &s.R[ri]
-               targ := r.Sym
-               if targ == nil {
-                       continue
-               }
-               if !targ.Attr.Reachable() {
-                       if r.Type == objabi.R_WEAKADDROFF {
-                               continue
-                       }
-                       Errorf(s, "dynamic relocation to unreachable symbol %s", targ.Name)
-               }
-               if r.Sym.Plt() == -2 && r.Sym.Got() != -2 { // make dynimport JMP table for PE object files.
-                       targ.SetPlt(int32(rel.Size))
-                       r.Sym = rel
-                       r.Add = int64(targ.Plt())
-
-                       // jmp *addr
-                       switch ctxt.Arch.Family {
-                       default:
-                               Errorf(s, "unsupported arch %v", ctxt.Arch.Family)
-                               return
-                       case sys.I386:
-                               rel.AddUint8(0xff)
-                               rel.AddUint8(0x25)
-                               rel.AddAddr(ctxt.Arch, targ)
-                               rel.AddUint8(0x90)
-                               rel.AddUint8(0x90)
-                       case sys.AMD64:
-                               rel.AddUint8(0xff)
-                               rel.AddUint8(0x24)
-                               rel.AddUint8(0x25)
-                               rel.AddAddrPlus4(targ, 0)
-                               rel.AddUint8(0x90)
-                       }
-               } else if r.Sym.Plt() >= 0 {
-                       r.Sym = rel
-                       r.Add = int64(targ.Plt())
-               }
-       }
-}
-
-// windynrelocsyms generates jump table to C library functions that will be
-// added later. windynrelocsyms writes the table into .rel symbol.
-func (ctxt *Link) windynrelocsyms() {
-       if !(ctxt.HeadType == objabi.Hwindows && iscgo && ctxt.LinkMode == LinkInternal) {
-               return
-       }
-
-       /* relocation table */
-       rel := ctxt.Syms.Lookup(".rel", 0)
-       rel.Attr |= sym.AttrReachable
-       rel.Type = sym.STEXT
-       ctxt.Textp = append(ctxt.Textp, rel)
-
-       for _, s := range ctxt.Textp {
-               if s == rel {
-                       continue
-               }
-               windynrelocsym(ctxt, rel, s)
-       }
-}
-
-func dynrelocsym(ctxt *Link, s *sym.Symbol) {
-       for ri := range s.R {
-               r := &s.R[ri]
-               if ctxt.BuildMode == BuildModePIE && ctxt.LinkMode == LinkInternal {
-                       // It's expected that some relocations will be done
-                       // later by relocsym (R_TLS_LE, R_ADDROFF), so
-                       // don't worry if Adddynrel returns false.
-                       thearch.Adddynrel(ctxt, s, r)
-                       continue
-               }
-
-               if r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT || r.Type >= objabi.ElfRelocOffset {
-                       if r.Sym != nil && !r.Sym.Attr.Reachable() {
-                               Errorf(s, "dynamic relocation to unreachable symbol %s", r.Sym.Name)
-                       }
-                       if !thearch.Adddynrel(ctxt, s, r) {
-                               Errorf(s, "unsupported dynamic relocation for symbol %s (type=%d (%s) stype=%d (%s))", r.Sym.Name, r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Sym.Type, r.Sym.Type)
-                       }
-               }
-       }
-}
-
-func dynreloc(ctxt *Link, data *[sym.SXREF][]*sym.Symbol) {
-       if ctxt.HeadType == objabi.Hwindows {
-               return
-       }
-       // -d suppresses dynamic loader format, so we may as well not
-       // compute these sections or mark their symbols as reachable.
-       if *FlagD {
-               return
-       }
-
-       for _, s := range ctxt.Textp {
-               dynrelocsym(ctxt, s)
-       }
-       for _, syms := range data {
-               for _, s := range syms {
-                       dynrelocsym(ctxt, s)
-               }
-       }
-       if ctxt.IsELF {
-               elfdynhash(ctxt)
-       }
-}
-
-func Codeblk(ctxt *Link, addr int64, size int64) {
-       CodeblkPad(ctxt, addr, size, zeros[:])
-}
-func CodeblkPad(ctxt *Link, addr int64, size int64, pad []byte) {
-       if *flagA {
-               ctxt.Logf("codeblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset())
-       }
-
-       blk(ctxt.Out, ctxt.Textp, addr, size, pad)
-
-       /* again for printing */
-       if !*flagA {
-               return
-       }
-
-       syms := ctxt.Textp
-       for i, s := range syms {
-               if !s.Attr.Reachable() {
-                       continue
-               }
-               if s.Value >= addr {
-                       syms = syms[i:]
-                       break
-               }
-       }
-
-       eaddr := addr + size
-       for _, s := range syms {
-               if !s.Attr.Reachable() {
-                       continue
-               }
-               if s.Value >= eaddr {
-                       break
-               }
-
-               if addr < s.Value {
-                       ctxt.Logf("%-20s %.8x|", "_", uint64(addr))
-                       for ; addr < s.Value; addr++ {
-                               ctxt.Logf(" %.2x", 0)
-                       }
-                       ctxt.Logf("\n")
-               }
-
-               ctxt.Logf("%.6x\t%-20s\n", uint64(addr), s.Name)
-               q := s.P
-
-               for len(q) >= 16 {
-                       ctxt.Logf("%.6x\t% x\n", uint64(addr), q[:16])
-                       addr += 16
-                       q = q[16:]
-               }
-
-               if len(q) > 0 {
-                       ctxt.Logf("%.6x\t% x\n", uint64(addr), q)
-                       addr += int64(len(q))
-               }
-       }
-
-       if addr < eaddr {
-               ctxt.Logf("%-20s %.8x|", "_", uint64(addr))
-               for ; addr < eaddr; addr++ {
-                       ctxt.Logf(" %.2x", 0)
-               }
-       }
-}
-
-func blk(out *OutBuf, syms []*sym.Symbol, addr, size int64, pad []byte) {
-       for i, s := range syms {
-               if !s.Attr.SubSymbol() && s.Value >= addr {
-                       syms = syms[i:]
-                       break
-               }
-       }
-
-       // This doesn't distinguish the memory size from the file
-       // size, and it lays out the file based on Symbol.Value, which
-       // is the virtual address. DWARF compression changes file sizes,
-       // so dwarfcompress will fix this up later if necessary.
-       eaddr := addr + size
-       for _, s := range syms {
-               if s.Attr.SubSymbol() {
-                       continue
-               }
-               if s.Value >= eaddr {
-                       break
-               }
-               if s.Value < addr {
-                       Errorf(s, "phase error: addr=%#x but sym=%#x type=%d", addr, s.Value, s.Type)
-                       errorexit()
-               }
-               if addr < s.Value {
-                       out.WriteStringPad("", int(s.Value-addr), pad)
-                       addr = s.Value
-               }
-               out.WriteSym(s)
-               addr += int64(len(s.P))
-               if addr < s.Value+s.Size {
-                       out.WriteStringPad("", int(s.Value+s.Size-addr), pad)
-                       addr = s.Value + s.Size
-               }
-               if addr != s.Value+s.Size {
-                       Errorf(s, "phase error: addr=%#x value+size=%#x", addr, s.Value+s.Size)
-                       errorexit()
-               }
-               if s.Value+s.Size >= eaddr {
-                       break
-               }
-       }
-
-       if addr < eaddr {
-               out.WriteStringPad("", int(eaddr-addr), pad)
-       }
-       out.Flush()
-}
-
-func Datblk(ctxt *Link, addr int64, size int64) {
-       writeDatblkToOutBuf(ctxt, ctxt.Out, addr, size)
-}
-
-// Used only on Wasm for now.
-func DatblkBytes(ctxt *Link, addr int64, size int64) []byte {
-       buf := bytes.NewBuffer(make([]byte, 0, size))
-       out := &OutBuf{w: bufio.NewWriter(buf)}
-       writeDatblkToOutBuf(ctxt, out, addr, size)
-       out.Flush()
-       return buf.Bytes()
-}
-
-func writeDatblkToOutBuf(ctxt *Link, out *OutBuf, addr int64, size int64) {
-       if *flagA {
-               ctxt.Logf("datblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset())
-       }
-
-       blk(out, datap, addr, size, zeros[:])
-
-       /* again for printing */
-       if !*flagA {
-               return
-       }
-
-       syms := datap
-       for i, sym := range syms {
-               if sym.Value >= addr {
-                       syms = syms[i:]
-                       break
-               }
-       }
-
-       eaddr := addr + size
-       for _, sym := range syms {
-               if sym.Value >= eaddr {
-                       break
-               }
-               if addr < sym.Value {
-                       ctxt.Logf("\t%.8x| 00 ...\n", uint64(addr))
-                       addr = sym.Value
-               }
-
-               ctxt.Logf("%s\n\t%.8x|", sym.Name, uint64(addr))
-               for i, b := range sym.P {
-                       if i > 0 && i%16 == 0 {
-                               ctxt.Logf("\n\t%.8x|", uint64(addr)+uint64(i))
-                       }
-                       ctxt.Logf(" %.2x", b)
-               }
-
-               addr += int64(len(sym.P))
-               for ; addr < sym.Value+sym.Size; addr++ {
-                       ctxt.Logf(" %.2x", 0)
-               }
-               ctxt.Logf("\n")
-
-               if ctxt.LinkMode != LinkExternal {
-                       continue
-               }
-               for i := range sym.R {
-                       r := &sym.R[i] // Copying sym.Reloc has measurable impact on performance
-                       rsname := ""
-                       rsval := int64(0)
-                       if r.Sym != nil {
-                               rsname = r.Sym.Name
-                               rsval = r.Sym.Value
-                       }
-                       typ := "?"
-                       switch r.Type {
-                       case objabi.R_ADDR:
-                               typ = "addr"
-                       case objabi.R_PCREL:
-                               typ = "pcrel"
-                       case objabi.R_CALL:
-                               typ = "call"
-                       }
-                       ctxt.Logf("\treloc %.8x/%d %s %s+%#x [%#x]\n", uint(sym.Value+int64(r.Off)), r.Siz, typ, rsname, r.Add, rsval+r.Add)
-               }
-       }
-
-       if addr < eaddr {
-               ctxt.Logf("\t%.8x| 00 ...\n", uint(addr))
-       }
-       ctxt.Logf("\t%.8x|\n", uint(eaddr))
-}
-
-func Dwarfblk(ctxt *Link, addr int64, size int64) {
-       if *flagA {
-               ctxt.Logf("dwarfblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset())
-       }
-
-       blk(ctxt.Out, dwarfp, addr, size, zeros[:])
-}
-
-var zeros [512]byte
-
-var (
-       strdata  = make(map[string]string)
-       strnames []string
-)
-
-func addstrdata1(ctxt *Link, arg string) {
-       eq := strings.Index(arg, "=")
-       dot := strings.LastIndex(arg[:eq+1], ".")
-       if eq < 0 || dot < 0 {
-               Exitf("-X flag requires argument of the form importpath.name=value")
-       }
-       pkg := arg[:dot]
-       if ctxt.BuildMode == BuildModePlugin && pkg == "main" {
-               pkg = *flagPluginPath
-       }
-       pkg = objabi.PathToPrefix(pkg)
-       name := pkg + arg[dot:eq]
-       value := arg[eq+1:]
-       if _, ok := strdata[name]; !ok {
-               strnames = append(strnames, name)
-       }
-       strdata[name] = value
-}
-
-// addstrdata sets the initial value of the string variable name to value.
-func addstrdata(ctxt *Link, name, value string) {
-       s := ctxt.Syms.ROLookup(name, 0)
-       if s == nil || s.Gotype == nil {
-               // Not defined in the loaded packages.
-               return
-       }
-       if s.Gotype.Name != "type.string" {
-               Errorf(s, "cannot set with -X: not a var of type string (%s)", s.Gotype.Name)
-               return
-       }
-       if s.Type == sym.SBSS {
-               s.Type = sym.SDATA
-       }
-
-       p := fmt.Sprintf("%s.str", s.Name)
-       sp := ctxt.Syms.Lookup(p, 0)
-
-       Addstring(sp, value)
-       sp.Type = sym.SRODATA
-
-       s.Size = 0
-       s.P = s.P[:0]
-       if s.Attr.ReadOnly() {
-               s.P = make([]byte, 0, ctxt.Arch.PtrSize*2)
-               s.Attr.Set(sym.AttrReadOnly, false)
-       }
-       s.R = s.R[:0]
-       reachable := s.Attr.Reachable()
-       s.AddAddr(ctxt.Arch, sp)
-       s.AddUint(ctxt.Arch, uint64(len(value)))
-
-       // addstring, addaddr, etc., mark the symbols as reachable.
-       // In this case that is not necessarily true, so stick to what
-       // we know before entering this function.
-       s.Attr.Set(sym.AttrReachable, reachable)
-
-       sp.Attr.Set(sym.AttrReachable, reachable)
-}
-
-func (ctxt *Link) dostrdata() {
-       for _, name := range strnames {
-               addstrdata(ctxt, name, strdata[name])
-       }
-}
-
-func Addstring(s *sym.Symbol, str string) int64 {
-       if s.Type == 0 {
-               s.Type = sym.SNOPTRDATA
-       }
-       s.Attr |= sym.AttrReachable
-       r := s.Size
-       if s.Name == ".shstrtab" {
-               elfsetstring(s, str, int(r))
-       }
-       s.P = append(s.P, str...)
-       s.P = append(s.P, 0)
-       s.Size = int64(len(s.P))
-       return r
-}
-
-// addgostring adds str, as a Go string value, to s. symname is the name of the
-// symbol used to define the string data and must be unique per linked object.
-func addgostring(ctxt *Link, s *sym.Symbol, symname, str string) {
-       sdata := ctxt.Syms.Lookup(symname, 0)
-       if sdata.Type != sym.Sxxx {
-               Errorf(s, "duplicate symname in addgostring: %s", symname)
-       }
-       sdata.Attr |= sym.AttrReachable
-       sdata.Attr |= sym.AttrLocal
-       sdata.Type = sym.SRODATA
-       sdata.Size = int64(len(str))
-       sdata.P = []byte(str)
-       s.AddAddr(ctxt.Arch, sdata)
-       s.AddUint(ctxt.Arch, uint64(len(str)))
-}
-
-func addinitarrdata(ctxt *Link, s *sym.Symbol) {
-       p := s.Name + ".ptr"
-       sp := ctxt.Syms.Lookup(p, 0)
-       sp.Type = sym.SINITARR
-       sp.Size = 0
-       sp.Attr |= sym.AttrDuplicateOK
-       sp.AddAddr(ctxt.Arch, s)
-}
-
-// symalign returns the required alignment for the given symbol s.
-func symalign(s *sym.Symbol) int32 {
-       min := int32(thearch.Minalign)
-       if s.Align >= min {
-               return s.Align
-       } else if s.Align != 0 {
-               return min
-       }
-       if strings.HasPrefix(s.Name, "go.string.") || strings.HasPrefix(s.Name, "type..namedata.") {
-               // String data is just bytes.
-               // If we align it, we waste a lot of space to padding.
-               return min
-       }
-       align := int32(thearch.Maxalign)
-       for int64(align) > s.Size && align > min {
-               align >>= 1
-       }
-       s.Align = align
-       return align
-}
-
-func aligndatsize(datsize int64, s *sym.Symbol) int64 {
-       return Rnd(datsize, int64(symalign(s)))
-}
-
-const debugGCProg = false
-
-type GCProg struct {
-       ctxt *Link
-       sym  *sym.Symbol
-       w    gcprog.Writer
-}
-
-func (p *GCProg) Init(ctxt *Link, name string) {
-       p.ctxt = ctxt
-       p.sym = ctxt.Syms.Lookup(name, 0)
-       p.w.Init(p.writeByte(ctxt))
-       if debugGCProg {
-               fmt.Fprintf(os.Stderr, "ld: start GCProg %s\n", name)
-               p.w.Debug(os.Stderr)
-       }
-}
-
-func (p *GCProg) writeByte(ctxt *Link) func(x byte) {
-       return func(x byte) {
-               p.sym.AddUint8(x)
-       }
-}
-
-func (p *GCProg) End(size int64) {
-       p.w.ZeroUntil(size / int64(p.ctxt.Arch.PtrSize))
-       p.w.End()
-       if debugGCProg {
-               fmt.Fprintf(os.Stderr, "ld: end GCProg\n")
-       }
-}
-
-func (p *GCProg) AddSym(s *sym.Symbol) {
-       typ := s.Gotype
-       // Things without pointers should be in sym.SNOPTRDATA or sym.SNOPTRBSS;
-       // everything we see should have pointers and should therefore have a type.
-       if typ == nil {
-               switch s.Name {
-               case "runtime.data", "runtime.edata", "runtime.bss", "runtime.ebss":
-                       // Ignore special symbols that are sometimes laid out
-                       // as real symbols. See comment about dyld on darwin in
-                       // the address function.
-                       return
-               }
-               Errorf(s, "missing Go type information for global symbol: size %d", s.Size)
-               return
-       }
-
-       ptrsize := int64(p.ctxt.Arch.PtrSize)
-       nptr := decodetypePtrdata(p.ctxt.Arch, typ.P) / ptrsize
-
-       if debugGCProg {
-               fmt.Fprintf(os.Stderr, "gcprog sym: %s at %d (ptr=%d+%d)\n", s.Name, s.Value, s.Value/ptrsize, nptr)
-       }
-
-       if decodetypeUsegcprog(p.ctxt.Arch, typ.P) == 0 {
-               // Copy pointers from mask into program.
-               mask := decodetypeGcmask(p.ctxt, typ)
-               for i := int64(0); i < nptr; i++ {
-                       if (mask[i/8]>>uint(i%8))&1 != 0 {
-                               p.w.Ptr(s.Value/ptrsize + i)
-                       }
-               }
-               return
-       }
-
-       // Copy program.
-       prog := decodetypeGcprog(p.ctxt, typ)
-       p.w.ZeroUntil(s.Value / ptrsize)
-       p.w.Append(prog[4:], nptr)
-}
-
-// dataSortKey is used to sort a slice of data symbol *sym.Symbol pointers.
-// The sort keys are kept inline to improve cache behavior while sorting.
-type dataSortKey struct {
-       size int64
-       name string
-       sym  *sym.Symbol
-}
-
-type bySizeAndName []dataSortKey
-
-func (d bySizeAndName) Len() int      { return len(d) }
-func (d bySizeAndName) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
-func (d bySizeAndName) Less(i, j int) bool {
-       s1, s2 := d[i], d[j]
-       if s1.size != s2.size {
-               return s1.size < s2.size
-       }
-       return s1.name < s2.name
-}
-
-// cutoff is the maximum data section size permitted by the linker
-// (see issue #9862).
-const cutoff = 2e9 // 2 GB (or so; looks better in errors than 2^31)
-
-func checkdatsize(ctxt *Link, datsize int64, symn sym.SymKind) {
-       if datsize > cutoff {
-               Errorf(nil, "too much data in section %v (over %v bytes)", symn, cutoff)
-       }
-}
-
-// datap is a collection of reachable data symbols in address order.
-// Generated by dodata.
-var datap []*sym.Symbol
-
-func (ctxt *Link) dodata() {
-       if (ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
-               // The values in moduledata are filled out by relocations
-               // pointing to the addresses of these special symbols.
-               // Typically these symbols have no size and are not laid
-               // out with their matching section.
-               //
-               // However on darwin, dyld will find the special symbol
-               // in the first loaded module, even though it is local.
-               //
-               // (An hypothesis, formed without looking in the dyld sources:
-               // these special symbols have no size, so their address
-               // matches a real symbol. The dynamic linker assumes we
-               // want the normal symbol with the same address and finds
-               // it in the other module.)
-               //
-               // To work around this we lay out the symbls whose
-               // addresses are vital for multi-module programs to work
-               // as normal symbols, and give them a little size.
-               //
-               // On AIX, as all DATA sections are merged together, ld might not put
-               // these symbols at the beginning of their respective section if there
-               // aren't real symbols, their alignment might not match the
-               // first symbol alignment. Therefore, there are explicitly put at the
-               // beginning of their section with the same alignment.
-               bss := ctxt.Syms.Lookup("runtime.bss", 0)
-               bss.Size = 8
-               bss.Attr.Set(sym.AttrSpecial, false)
-
-               ctxt.Syms.Lookup("runtime.ebss", 0).Attr.Set(sym.AttrSpecial, false)
-
-               data := ctxt.Syms.Lookup("runtime.data", 0)
-               data.Size = 8
-               data.Attr.Set(sym.AttrSpecial, false)
-
-               edata := ctxt.Syms.Lookup("runtime.edata", 0)
-               edata.Attr.Set(sym.AttrSpecial, false)
-               if ctxt.HeadType == objabi.Haix {
-                       // XCOFFTOC symbols are part of .data section.
-                       edata.Type = sym.SXCOFFTOC
-               }
-
-               types := ctxt.Syms.Lookup("runtime.types", 0)
-               types.Type = sym.STYPE
-               types.Size = 8
-               types.Attr.Set(sym.AttrSpecial, false)
-
-               etypes := ctxt.Syms.Lookup("runtime.etypes", 0)
-               etypes.Type = sym.SFUNCTAB
-               etypes.Attr.Set(sym.AttrSpecial, false)
-
-               if ctxt.HeadType == objabi.Haix {
-                       rodata := ctxt.Syms.Lookup("runtime.rodata", 0)
-                       rodata.Type = sym.SSTRING
-                       rodata.Size = 8
-                       rodata.Attr.Set(sym.AttrSpecial, false)
-
-                       ctxt.Syms.Lookup("runtime.erodata", 0).Attr.Set(sym.AttrSpecial, false)
-
-               }
-       }
-
-       // Collect data symbols by type into data.
-       var data [sym.SXREF][]*sym.Symbol
-       for _, s := range ctxt.Syms.Allsym {
-               if !s.Attr.Reachable() || s.Attr.Special() || s.Attr.SubSymbol() {
-                       continue
-               }
-               if s.Type <= sym.STEXT || s.Type >= sym.SXREF {
-                       continue
-               }
-               data[s.Type] = append(data[s.Type], s)
-       }
-
-       // Now that we have the data symbols, but before we start
-       // to assign addresses, record all the necessary
-       // dynamic relocations. These will grow the relocation
-       // symbol, which is itself data.
-       //
-       // On darwin, we need the symbol table numbers for dynreloc.
-       if ctxt.HeadType == objabi.Hdarwin {
-               machosymorder(ctxt)
-       }
-       dynreloc(ctxt, &data)
-
-       if ctxt.UseRelro() {
-               // "read only" data with relocations needs to go in its own section
-               // when building a shared library. We do this by boosting objects of
-               // type SXXX with relocations to type SXXXRELRO.
-               for _, symnro := range sym.ReadOnly {
-                       symnrelro := sym.RelROMap[symnro]
-
-                       ro := []*sym.Symbol{}
-                       relro := data[symnrelro]
-
-                       for _, s := range data[symnro] {
-                               isRelro := len(s.R) > 0
-                               switch s.Type {
-                               case sym.STYPE, sym.STYPERELRO, sym.SGOFUNCRELRO:
-                                       // Symbols are not sorted yet, so it is possible
-                                       // that an Outer symbol has been changed to a
-                                       // relro Type before it reaches here.
-                                       isRelro = true
-                               case sym.SFUNCTAB:
-                                       if ctxt.HeadType == objabi.Haix && s.Name == "runtime.etypes" {
-                                               // runtime.etypes must be at the end of
-                                               // the relro datas.
-                                               isRelro = true
-                                       }
-                               }
-                               if isRelro {
-                                       s.Type = symnrelro
-                                       if s.Outer != nil {
-                                               s.Outer.Type = s.Type
-                                       }
-                                       relro = append(relro, s)
-                               } else {
-                                       ro = append(ro, s)
-                               }
-                       }
-
-                       // Check that we haven't made two symbols with the same .Outer into
-                       // different types (because references two symbols with non-nil Outer
-                       // become references to the outer symbol + offset it's vital that the
-                       // symbol and the outer end up in the same section).
-                       for _, s := range relro {
-                               if s.Outer != nil && s.Outer.Type != s.Type {
-                                       Errorf(s, "inconsistent types for symbol and its Outer %s (%v != %v)",
-                                               s.Outer.Name, s.Type, s.Outer.Type)
-                               }
-                       }
-
-                       data[symnro] = ro
-                       data[symnrelro] = relro
-               }
-       }
-
-       // Sort symbols.
-       var dataMaxAlign [sym.SXREF]int32
-       var wg sync.WaitGroup
-       for symn := range data {
-               symn := sym.SymKind(symn)
-               wg.Add(1)
-               go func() {
-                       data[symn], dataMaxAlign[symn] = dodataSect(ctxt, symn, data[symn])
-                       wg.Done()
-               }()
-       }
-       wg.Wait()
-
-       if ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal {
-               // These symbols must have the same alignment as their section.
-               // Otherwize, ld might change the layout of Go sections.
-               ctxt.Syms.ROLookup("runtime.data", 0).Align = dataMaxAlign[sym.SDATA]
-               ctxt.Syms.ROLookup("runtime.bss", 0).Align = dataMaxAlign[sym.SBSS]
-       }
-
-       // Allocate sections.
-       // Data is processed before segtext, because we need
-       // to see all symbols in the .data and .bss sections in order
-       // to generate garbage collection information.
-       datsize := int64(0)
-
-       // Writable data sections that do not need any specialized handling.
-       writable := []sym.SymKind{
-               sym.SBUILDINFO,
-               sym.SELFSECT,
-               sym.SMACHO,
-               sym.SMACHOGOT,
-               sym.SWINDOWS,
-       }
-       for _, symn := range writable {
-               for _, s := range data[symn] {
-                       sect := addsection(ctxt.Arch, &Segdata, s.Name, 06)
-                       sect.Align = symalign(s)
-                       datsize = Rnd(datsize, int64(sect.Align))
-                       sect.Vaddr = uint64(datsize)
-                       s.Sect = sect
-                       s.Type = sym.SDATA
-                       s.Value = int64(uint64(datsize) - sect.Vaddr)
-                       datsize += s.Size
-                       sect.Length = uint64(datsize) - sect.Vaddr
-               }
-               checkdatsize(ctxt, datsize, symn)
-       }
-
-       // .got (and .toc on ppc64)
-       if len(data[sym.SELFGOT]) > 0 {
-               sect := addsection(ctxt.Arch, &Segdata, ".got", 06)
-               sect.Align = dataMaxAlign[sym.SELFGOT]
-               datsize = Rnd(datsize, int64(sect.Align))
-               sect.Vaddr = uint64(datsize)
-               for _, s := range data[sym.SELFGOT] {
-                       datsize = aligndatsize(datsize, s)
-                       s.Sect = sect
-                       s.Type = sym.SDATA
-                       s.Value = int64(uint64(datsize) - sect.Vaddr)
-
-                       // Resolve .TOC. symbol for this object file (ppc64)
-                       toc := ctxt.Syms.ROLookup(".TOC.", int(s.Version))
-                       if toc != nil {
-                               toc.Sect = sect
-                               toc.Outer = s
-                               toc.Sub = s.Sub
-                               s.Sub = toc
-
-                               toc.Value = 0x8000
-                       }
-
-                       datsize += s.Size
-               }
-               checkdatsize(ctxt, datsize, sym.SELFGOT)
-               sect.Length = uint64(datsize) - sect.Vaddr
-       }
-
-       /* pointer-free data */
-       sect := addsection(ctxt.Arch, &Segdata, ".noptrdata", 06)
-       sect.Align = dataMaxAlign[sym.SNOPTRDATA]
-       datsize = Rnd(datsize, int64(sect.Align))
-       sect.Vaddr = uint64(datsize)
-       ctxt.Syms.Lookup("runtime.noptrdata", 0).Sect = sect
-       ctxt.Syms.Lookup("runtime.enoptrdata", 0).Sect = sect
-       for _, s := range data[sym.SNOPTRDATA] {
-               datsize = aligndatsize(datsize, s)
-               s.Sect = sect
-               s.Type = sym.SDATA
-               s.Value = int64(uint64(datsize) - sect.Vaddr)
-               datsize += s.Size
-       }
-       checkdatsize(ctxt, datsize, sym.SNOPTRDATA)
-       sect.Length = uint64(datsize) - sect.Vaddr
-
-       hasinitarr := ctxt.linkShared
-
-       /* shared library initializer */
-       switch ctxt.BuildMode {
-       case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin:
-               hasinitarr = true
-       }
-
-       if ctxt.HeadType == objabi.Haix {
-               if len(data[sym.SINITARR]) > 0 {
-                       Errorf(nil, "XCOFF format doesn't allow .init_array section")
-               }
-       }
-
-       if hasinitarr && len(data[sym.SINITARR]) > 0 {
-               sect := addsection(ctxt.Arch, &Segdata, ".init_array", 06)
-               sect.Align = dataMaxAlign[sym.SINITARR]
-               datsize = Rnd(datsize, int64(sect.Align))
-               sect.Vaddr = uint64(datsize)
-               for _, s := range data[sym.SINITARR] {
-                       datsize = aligndatsize(datsize, s)
-                       s.Sect = sect
-                       s.Value = int64(uint64(datsize) - sect.Vaddr)
-                       datsize += s.Size
-               }
-               sect.Length = uint64(datsize) - sect.Vaddr
-               checkdatsize(ctxt, datsize, sym.SINITARR)
-       }
-
-       /* data */
-       sect = addsection(ctxt.Arch, &Segdata, ".data", 06)
-       sect.Align = dataMaxAlign[sym.SDATA]
-       datsize = Rnd(datsize, int64(sect.Align))
-       sect.Vaddr = uint64(datsize)
-       ctxt.Syms.Lookup("runtime.data", 0).Sect = sect
-       ctxt.Syms.Lookup("runtime.edata", 0).Sect = sect
-       var gc GCProg
-       gc.Init(ctxt, "runtime.gcdata")
-       for _, s := range data[sym.SDATA] {
-               s.Sect = sect
-               s.Type = sym.SDATA
-               datsize = aligndatsize(datsize, s)
-               s.Value = int64(uint64(datsize) - sect.Vaddr)
-               gc.AddSym(s)
-               datsize += s.Size
-       }
-       gc.End(datsize - int64(sect.Vaddr))
-       // On AIX, TOC entries must be the last of .data
-       // These aren't part of gc as they won't change during the runtime.
-       for _, s := range data[sym.SXCOFFTOC] {
-               s.Sect = sect
-               s.Type = sym.SDATA
-               datsize = aligndatsize(datsize, s)
-               s.Value = int64(uint64(datsize) - sect.Vaddr)
-               datsize += s.Size
-       }
-       checkdatsize(ctxt, datsize, sym.SDATA)
-       sect.Length = uint64(datsize) - sect.Vaddr
-
-       /* bss */
-       sect = addsection(ctxt.Arch, &Segdata, ".bss", 06)
-       sect.Align = dataMaxAlign[sym.SBSS]
-       datsize = Rnd(datsize, int64(sect.Align))
-       sect.Vaddr = uint64(datsize)
-       ctxt.Syms.Lookup("runtime.bss", 0).Sect = sect
-       ctxt.Syms.Lookup("runtime.ebss", 0).Sect = sect
-       gc = GCProg{}
-       gc.Init(ctxt, "runtime.gcbss")
-       for _, s := range data[sym.SBSS] {
-               s.Sect = sect
-               datsize = aligndatsize(datsize, s)
-               s.Value = int64(uint64(datsize) - sect.Vaddr)
-               gc.AddSym(s)
-               datsize += s.Size
-       }
-       checkdatsize(ctxt, datsize, sym.SBSS)
-       sect.Length = uint64(datsize) - sect.Vaddr
-       gc.End(int64(sect.Length))
-
-       /* pointer-free bss */
-       sect = addsection(ctxt.Arch, &Segdata, ".noptrbss", 06)
-       sect.Align = dataMaxAlign[sym.SNOPTRBSS]
-       datsize = Rnd(datsize, int64(sect.Align))
-       sect.Vaddr = uint64(datsize)
-       ctxt.Syms.Lookup("runtime.noptrbss", 0).Sect = sect
-       ctxt.Syms.Lookup("runtime.enoptrbss", 0).Sect = sect
-       for _, s := range data[sym.SNOPTRBSS] {
-               datsize = aligndatsize(datsize, s)
-               s.Sect = sect
-               s.Value = int64(uint64(datsize) - sect.Vaddr)
-               datsize += s.Size
-       }
-       sect.Length = uint64(datsize) - sect.Vaddr
-       ctxt.Syms.Lookup("runtime.end", 0).Sect = sect
-       checkdatsize(ctxt, datsize, sym.SNOPTRBSS)
-
-       // Coverage instrumentation counters for libfuzzer.
-       if len(data[sym.SLIBFUZZER_EXTRA_COUNTER]) > 0 {
-               sect := addsection(ctxt.Arch, &Segdata, "__libfuzzer_extra_counters", 06)
-               sect.Align = dataMaxAlign[sym.SLIBFUZZER_EXTRA_COUNTER]
-               datsize = Rnd(datsize, int64(sect.Align))
-               sect.Vaddr = uint64(datsize)
-               for _, s := range data[sym.SLIBFUZZER_EXTRA_COUNTER] {
-                       datsize = aligndatsize(datsize, s)
-                       s.Sect = sect
-                       s.Value = int64(uint64(datsize) - sect.Vaddr)
-                       datsize += s.Size
-               }
-               sect.Length = uint64(datsize) - sect.Vaddr
-               checkdatsize(ctxt, datsize, sym.SLIBFUZZER_EXTRA_COUNTER)
-       }
-
-       if len(data[sym.STLSBSS]) > 0 {
-               var sect *sym.Section
-               if (ctxt.IsELF || ctxt.HeadType == objabi.Haix) && (ctxt.LinkMode == LinkExternal || !*FlagD) {
-                       sect = addsection(ctxt.Arch, &Segdata, ".tbss", 06)
-                       sect.Align = int32(ctxt.Arch.PtrSize)
-                       sect.Vaddr = 0
-               }
-               datsize = 0
-
-               for _, s := range data[sym.STLSBSS] {
-                       datsize = aligndatsize(datsize, s)
-                       s.Sect = sect
-                       s.Value = datsize
-                       datsize += s.Size
-               }
-               checkdatsize(ctxt, datsize, sym.STLSBSS)
-
-               if sect != nil {
-                       sect.Length = uint64(datsize)
-               }
-       }
-
-       /*
-        * We finished data, begin read-only data.
-        * Not all systems support a separate read-only non-executable data section.
-        * ELF and Windows PE systems do.
-        * OS X and Plan 9 do not.
-        * And if we're using external linking mode, the point is moot,
-        * since it's not our decision; that code expects the sections in
-        * segtext.
-        */
-       var segro *sym.Segment
-       if ctxt.IsELF && ctxt.LinkMode == LinkInternal {
-               segro = &Segrodata
-       } else if ctxt.HeadType == objabi.Hwindows {
-               segro = &Segrodata
-       } else {
-               segro = &Segtext
-       }
-
-       datsize = 0
-
-       /* read-only executable ELF, Mach-O sections */
-       if len(data[sym.STEXT]) != 0 {
-               Errorf(nil, "dodata found an sym.STEXT symbol: %s", data[sym.STEXT][0].Name)
-       }
-       for _, s := range data[sym.SELFRXSECT] {
-               sect := addsection(ctxt.Arch, &Segtext, s.Name, 04)
-               sect.Align = symalign(s)
-               datsize = Rnd(datsize, int64(sect.Align))
-               sect.Vaddr = uint64(datsize)
-               s.Sect = sect
-               s.Type = sym.SRODATA
-               s.Value = int64(uint64(datsize) - sect.Vaddr)
-               datsize += s.Size
-               sect.Length = uint64(datsize) - sect.Vaddr
-               checkdatsize(ctxt, datsize, sym.SELFRXSECT)
-       }
-
-       /* read-only data */
-       sect = addsection(ctxt.Arch, segro, ".rodata", 04)
-
-       sect.Vaddr = 0
-       ctxt.Syms.Lookup("runtime.rodata", 0).Sect = sect
-       ctxt.Syms.Lookup("runtime.erodata", 0).Sect = sect
-       if !ctxt.UseRelro() {
-               ctxt.Syms.Lookup("runtime.types", 0).Sect = sect
-               ctxt.Syms.Lookup("runtime.etypes", 0).Sect = sect
-       }
-       for _, symn := range sym.ReadOnly {
-               align := dataMaxAlign[symn]
-               if sect.Align < align {
-                       sect.Align = align
-               }
-       }
-       datsize = Rnd(datsize, int64(sect.Align))
-       for _, symn := range sym.ReadOnly {
-               symnStartValue := datsize
-               for _, s := range data[symn] {
-                       datsize = aligndatsize(datsize, s)
-                       s.Sect = sect
-                       s.Type = sym.SRODATA
-                       s.Value = int64(uint64(datsize) - sect.Vaddr)
-                       datsize += s.Size
-               }
-               checkdatsize(ctxt, datsize, symn)
-               if ctxt.HeadType == objabi.Haix {
-                       // Read-only symbols might be wrapped inside their outer
-                       // symbol.
-                       // XCOFF symbol table needs to know the size of
-                       // these outer symbols.
-                       xcoffUpdateOuterSize(ctxt, datsize-symnStartValue, symn)
-               }
-       }
-       sect.Length = uint64(datsize) - sect.Vaddr
-
-       /* read-only ELF, Mach-O sections */
-       for _, s := range data[sym.SELFROSECT] {
-               sect = addsection(ctxt.Arch, segro, s.Name, 04)
-               sect.Align = symalign(s)
-               datsize = Rnd(datsize, int64(sect.Align))
-               sect.Vaddr = uint64(datsize)
-               s.Sect = sect
-               s.Type = sym.SRODATA
-               s.Value = int64(uint64(datsize) - sect.Vaddr)
-               datsize += s.Size
-               sect.Length = uint64(datsize) - sect.Vaddr
-       }
-       checkdatsize(ctxt, datsize, sym.SELFROSECT)
-
-       for _, s := range data[sym.SMACHOPLT] {
-               sect = addsection(ctxt.Arch, segro, s.Name, 04)
-               sect.Align = symalign(s)
-               datsize = Rnd(datsize, int64(sect.Align))
-               sect.Vaddr = uint64(datsize)
-               s.Sect = sect
-               s.Type = sym.SRODATA
-               s.Value = int64(uint64(datsize) - sect.Vaddr)
-               datsize += s.Size
-               sect.Length = uint64(datsize) - sect.Vaddr
-       }
-       checkdatsize(ctxt, datsize, sym.SMACHOPLT)
-
-       // There is some data that are conceptually read-only but are written to by
-       // relocations. On GNU systems, we can arrange for the dynamic linker to
-       // mprotect sections after relocations are applied by giving them write
-       // permissions in the object file and calling them ".data.rel.ro.FOO". We
-       // divide the .rodata section between actual .rodata and .data.rel.ro.rodata,
-       // but for the other sections that this applies to, we just write a read-only
-       // .FOO section or a read-write .data.rel.ro.FOO section depending on the
-       // situation.
-       // TODO(mwhudson): It would make sense to do this more widely, but it makes
-       // the system linker segfault on darwin.
-       addrelrosection := func(suffix string) *sym.Section {
-               return addsection(ctxt.Arch, segro, suffix, 04)
-       }
-
-       if ctxt.UseRelro() {
-               segrelro := &Segrelrodata
-               if ctxt.LinkMode == LinkExternal && ctxt.HeadType != objabi.Haix {
-                       // Using a separate segment with an external
-                       // linker results in some programs moving
-                       // their data sections unexpectedly, which
-                       // corrupts the moduledata. So we use the
-                       // rodata segment and let the external linker
-                       // sort out a rel.ro segment.
-                       segrelro = segro
-               } else {
-                       // Reset datsize for new segment.
-                       datsize = 0
-               }
-
-               addrelrosection = func(suffix string) *sym.Section {
-                       return addsection(ctxt.Arch, segrelro, ".data.rel.ro"+suffix, 06)
-               }
-
-               /* data only written by relocations */
-               sect = addrelrosection("")
-
-               ctxt.Syms.Lookup("runtime.types", 0).Sect = sect
-               ctxt.Syms.Lookup("runtime.etypes", 0).Sect = sect
-
-               for _, symnro := range sym.ReadOnly {
-                       symn := sym.RelROMap[symnro]
-                       align := dataMaxAlign[symn]
-                       if sect.Align < align {
-                               sect.Align = align
-                       }
-               }
-               datsize = Rnd(datsize, int64(sect.Align))
-               sect.Vaddr = uint64(datsize)
-
-               for i, symnro := range sym.ReadOnly {
-                       if i == 0 && symnro == sym.STYPE && ctxt.HeadType != objabi.Haix {
-                               // Skip forward so that no type
-                               // reference uses a zero offset.
-                               // This is unlikely but possible in small
-                               // programs with no other read-only data.
-                               datsize++
-                       }
-
-                       symn := sym.RelROMap[symnro]
-                       symnStartValue := datsize
-                       for _, s := range data[symn] {
-                               datsize = aligndatsize(datsize, s)
-                               if s.Outer != nil && s.Outer.Sect != nil && s.Outer.Sect != sect {
-                                       Errorf(s, "s.Outer (%s) in different section from s, %s != %s", s.Outer.Name, s.Outer.Sect.Name, sect.Name)
-                               }
-                               s.Sect = sect
-                               s.Type = sym.SRODATA
-                               s.Value = int64(uint64(datsize) - sect.Vaddr)
-                               datsize += s.Size
-                       }
-                       checkdatsize(ctxt, datsize, symn)
-                       if ctxt.HeadType == objabi.Haix {
-                               // Read-only symbols might be wrapped inside their outer
-                               // symbol.
-                               // XCOFF symbol table needs to know the size of
-                               // these outer symbols.
-                               xcoffUpdateOuterSize(ctxt, datsize-symnStartValue, symn)
-                       }
-               }
-
-               sect.Length = uint64(datsize) - sect.Vaddr
-       }
-
-       /* typelink */
-       sect = addrelrosection(".typelink")
-       sect.Align = dataMaxAlign[sym.STYPELINK]
-       datsize = Rnd(datsize, int64(sect.Align))
-       sect.Vaddr = uint64(datsize)
-       typelink := ctxt.Syms.Lookup("runtime.typelink", 0)
-       typelink.Sect = sect
-       typelink.Type = sym.SRODATA
-       datsize += typelink.Size
-       checkdatsize(ctxt, datsize, sym.STYPELINK)
-       sect.Length = uint64(datsize) - sect.Vaddr
-
-       /* itablink */
-       sect = addrelrosection(".itablink")
-       sect.Align = dataMaxAlign[sym.SITABLINK]
-       datsize = Rnd(datsize, int64(sect.Align))
-       sect.Vaddr = uint64(datsize)
-       ctxt.Syms.Lookup("runtime.itablink", 0).Sect = sect
-       ctxt.Syms.Lookup("runtime.eitablink", 0).Sect = sect
-       for _, s := range data[sym.SITABLINK] {
-               datsize = aligndatsize(datsize, s)
-               s.Sect = sect
-               s.Type = sym.SRODATA
-               s.Value = int64(uint64(datsize) - sect.Vaddr)
-               datsize += s.Size
-       }
-       checkdatsize(ctxt, datsize, sym.SITABLINK)
-       sect.Length = uint64(datsize) - sect.Vaddr
-       if ctxt.HeadType == objabi.Haix {
-               // Store .itablink size because its symbols are wrapped
-               // under an outer symbol: runtime.itablink.
-               xcoffUpdateOuterSize(ctxt, int64(sect.Length), sym.SITABLINK)
-       }
-
-       /* gosymtab */
-       sect = addrelrosection(".gosymtab")
-       sect.Align = dataMaxAlign[sym.SSYMTAB]
-       datsize = Rnd(datsize, int64(sect.Align))
-       sect.Vaddr = uint64(datsize)
-       ctxt.Syms.Lookup("runtime.symtab", 0).Sect = sect
-       ctxt.Syms.Lookup("runtime.esymtab", 0).Sect = sect
-       for _, s := range data[sym.SSYMTAB] {
-               datsize = aligndatsize(datsize, s)
-               s.Sect = sect
-               s.Type = sym.SRODATA
-               s.Value = int64(uint64(datsize) - sect.Vaddr)
-               datsize += s.Size
-       }
-       checkdatsize(ctxt, datsize, sym.SSYMTAB)
-       sect.Length = uint64(datsize) - sect.Vaddr
-
-       /* gopclntab */
-       sect = addrelrosection(".gopclntab")
-       sect.Align = dataMaxAlign[sym.SPCLNTAB]
-       datsize = Rnd(datsize, int64(sect.Align))
-       sect.Vaddr = uint64(datsize)
-       ctxt.Syms.Lookup("runtime.pclntab", 0).Sect = sect
-       ctxt.Syms.Lookup("runtime.epclntab", 0).Sect = sect
-       for _, s := range data[sym.SPCLNTAB] {
-               datsize = aligndatsize(datsize, s)
-               s.Sect = sect
-               s.Type = sym.SRODATA
-               s.Value = int64(uint64(datsize) - sect.Vaddr)
-               datsize += s.Size
-       }
-       checkdatsize(ctxt, datsize, sym.SRODATA)
-       sect.Length = uint64(datsize) - sect.Vaddr
-
-       // 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
-       if datsize != int64(uint32(datsize)) {
-               Errorf(nil, "read-only data segment too large: %d", datsize)
-       }
-
-       for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ {
-               datap = append(datap, data[symn]...)
-       }
-
-       dwarfGenerateDebugSyms(ctxt)
-
-       var i int
-       for ; i < len(dwarfp); i++ {
-               s := dwarfp[i]
-               if s.Type != sym.SDWARFSECT {
-                       break
-               }
-
-               sect = addsection(ctxt.Arch, &Segdwarf, s.Name, 04)
-               sect.Align = 1
-               datsize = Rnd(datsize, int64(sect.Align))
-               sect.Vaddr = uint64(datsize)
-               s.Sect = sect
-               s.Type = sym.SRODATA
-               s.Value = int64(uint64(datsize) - sect.Vaddr)
-               datsize += s.Size
-               sect.Length = uint64(datsize) - sect.Vaddr
-       }
-       checkdatsize(ctxt, datsize, sym.SDWARFSECT)
-
-       for i < len(dwarfp) {
-               curType := dwarfp[i].Type
-               var sect *sym.Section
-               switch curType {
-               case sym.SDWARFINFO:
-                       sect = addsection(ctxt.Arch, &Segdwarf, ".debug_info", 04)
-               case sym.SDWARFRANGE:
-                       sect = addsection(ctxt.Arch, &Segdwarf, ".debug_ranges", 04)
-               case sym.SDWARFLOC:
-                       sect = addsection(ctxt.Arch, &Segdwarf, ".debug_loc", 04)
-               default:
-                       // Error is unrecoverable, so panic.
-                       panic(fmt.Sprintf("unknown DWARF section %v", curType))
-               }
-
-               sect.Align = 1
-               datsize = Rnd(datsize, int64(sect.Align))
-               sect.Vaddr = uint64(datsize)
-               for ; i < len(dwarfp); i++ {
-                       s := dwarfp[i]
-                       if s.Type != curType {
-                               break
-                       }
-                       s.Sect = sect
-                       s.Type = sym.SRODATA
-                       s.Value = int64(uint64(datsize) - sect.Vaddr)
-                       s.Attr |= sym.AttrLocal
-                       datsize += s.Size
-
-                       if ctxt.HeadType == objabi.Haix && curType == sym.SDWARFLOC {
-                               // Update the size of .debug_loc for this symbol's
-                               // package.
-                               addDwsectCUSize(".debug_loc", s.File, uint64(s.Size))
-                       }
-               }
-               sect.Length = uint64(datsize) - sect.Vaddr
-               checkdatsize(ctxt, datsize, curType)
-       }
-
-       /* number the sections */
-       n := int32(1)
-
-       for _, sect := range Segtext.Sections {
-               sect.Extnum = int16(n)
-               n++
-       }
-       for _, sect := range Segrodata.Sections {
-               sect.Extnum = int16(n)
-               n++
-       }
-       for _, sect := range Segrelrodata.Sections {
-               sect.Extnum = int16(n)
-               n++
-       }
-       for _, sect := range Segdata.Sections {
-               sect.Extnum = int16(n)
-               n++
-       }
-       for _, sect := range Segdwarf.Sections {
-               sect.Extnum = int16(n)
-               n++
-       }
-}
-
-func dodataSect(ctxt *Link, symn sym.SymKind, syms []*sym.Symbol) (result []*sym.Symbol, maxAlign int32) {
-       if ctxt.HeadType == objabi.Hdarwin {
-               // Some symbols may no longer belong in syms
-               // due to movement in machosymorder.
-               newSyms := make([]*sym.Symbol, 0, len(syms))
-               for _, s := range syms {
-                       if s.Type == symn {
-                               newSyms = append(newSyms, s)
-                       }
-               }
-               syms = newSyms
-       }
-
-       var head, tail *sym.Symbol
-       symsSort := make([]dataSortKey, 0, len(syms))
-       for _, s := range syms {
-               if s.Attr.OnList() {
-                       log.Fatalf("symbol %s listed multiple times", s.Name)
-               }
-               s.Attr |= sym.AttrOnList
-               switch {
-               case s.Size < int64(len(s.P)):
-                       Errorf(s, "initialize bounds (%d < %d)", s.Size, len(s.P))
-               case s.Size < 0:
-                       Errorf(s, "negative size (%d bytes)", s.Size)
-               case s.Size > cutoff:
-                       Errorf(s, "symbol too large (%d bytes)", s.Size)
-               }
-
-               // If the usually-special section-marker symbols are being laid
-               // out as regular symbols, put them either at the beginning or
-               // end of their section.
-               if (ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
-                       switch s.Name {
-                       case "runtime.text", "runtime.bss", "runtime.data", "runtime.types", "runtime.rodata":
-                               head = s
-                               continue
-                       case "runtime.etext", "runtime.ebss", "runtime.edata", "runtime.etypes", "runtime.erodata":
-                               tail = s
-                               continue
-                       }
-               }
-
-               key := dataSortKey{
-                       size: s.Size,
-                       name: s.Name,
-                       sym:  s,
-               }
-
-               switch s.Type {
-               case sym.SELFGOT:
-                       // For ppc64, we want to interleave the .got and .toc sections
-                       // from input files. Both are type sym.SELFGOT, so in that case
-                       // we skip size comparison and fall through to the name
-                       // comparison (conveniently, .got sorts before .toc).
-                       key.size = 0
-               }
-
-               symsSort = append(symsSort, key)
-       }
-
-       sort.Sort(bySizeAndName(symsSort))
-
-       off := 0
-       if head != nil {
-               syms[0] = head
-               off++
-       }
-       for i, symSort := range symsSort {
-               syms[i+off] = symSort.sym
-               align := symalign(symSort.sym)
-               if maxAlign < align {
-                       maxAlign = align
-               }
-       }
-       if tail != nil {
-               syms[len(syms)-1] = tail
-       }
-
-       if ctxt.IsELF && symn == sym.SELFROSECT {
-               // Make .rela and .rela.plt contiguous, the ELF ABI requires this
-               // and Solaris actually cares.
-               reli, plti := -1, -1
-               for i, s := range syms {
-                       switch s.Name {
-                       case ".rel.plt", ".rela.plt":
-                               plti = i
-                       case ".rel", ".rela":
-                               reli = i
-                       }
-               }
-               if reli >= 0 && plti >= 0 && plti != reli+1 {
-                       var first, second int
-                       if plti > reli {
-                               first, second = reli, plti
-                       } else {
-                               first, second = plti, reli
-                       }
-                       rel, plt := syms[reli], syms[plti]
-                       copy(syms[first+2:], syms[first+1:second])
-                       syms[first+0] = rel
-                       syms[first+1] = plt
-
-                       // Make sure alignment doesn't introduce a gap.
-                       // Setting the alignment explicitly prevents
-                       // symalign from basing it on the size and
-                       // getting it wrong.
-                       rel.Align = int32(ctxt.Arch.RegSize)
-                       plt.Align = int32(ctxt.Arch.RegSize)
-               }
-       }
-
-       return syms, maxAlign
-}
-
-// Add buildid to beginning of text segment, on non-ELF systems.
-// Non-ELF binary formats are not always flexible enough to
-// give us a place to put the Go build ID. On those systems, we put it
-// at the very beginning of the text segment.
-// This ``header'' is read by cmd/go.
-func (ctxt *Link) textbuildid() {
-       if ctxt.IsELF || ctxt.BuildMode == BuildModePlugin || *flagBuildid == "" {
-               return
-       }
-
-       s := ctxt.Syms.Lookup("go.buildid", 0)
-       s.Attr |= sym.AttrReachable
-       // The \xff is invalid UTF-8, meant to make it less likely
-       // to find one of these accidentally.
-       data := "\xff Go build ID: " + strconv.Quote(*flagBuildid) + "\n \xff"
-       s.Type = sym.STEXT
-       s.P = []byte(data)
-       s.Size = int64(len(s.P))
-
-       ctxt.Textp = append(ctxt.Textp, nil)
-       copy(ctxt.Textp[1:], ctxt.Textp)
-       ctxt.Textp[0] = s
-}
-
-func (ctxt *Link) buildinfo() {
-       if ctxt.linkShared || ctxt.BuildMode == BuildModePlugin {
-               // -linkshared and -buildmode=plugin get confused
-               // about the relocations in go.buildinfo
-               // pointing at the other data sections.
-               // The version information is only available in executables.
-               return
-       }
-
-       s := ctxt.Syms.Lookup(".go.buildinfo", 0)
-       s.Attr |= sym.AttrReachable
-       s.Type = sym.SBUILDINFO
-       s.Align = 16
-       // The \xff is invalid UTF-8, meant to make it less likely
-       // to find one of these accidentally.
-       const prefix = "\xff Go buildinf:" // 14 bytes, plus 2 data bytes filled in below
-       data := make([]byte, 32)
-       copy(data, prefix)
-       data[len(prefix)] = byte(ctxt.Arch.PtrSize)
-       data[len(prefix)+1] = 0
-       if ctxt.Arch.ByteOrder == binary.BigEndian {
-               data[len(prefix)+1] = 1
-       }
-       s.P = data
-       s.Size = int64(len(s.P))
-       s1 := ctxt.Syms.Lookup("runtime.buildVersion", 0)
-       s2 := ctxt.Syms.Lookup("runtime.modinfo", 0)
-       s.R = []sym.Reloc{
-               {Off: 16, Siz: uint8(ctxt.Arch.PtrSize), Type: objabi.R_ADDR, Sym: s1},
-               {Off: 16 + int32(ctxt.Arch.PtrSize), Siz: uint8(ctxt.Arch.PtrSize), Type: objabi.R_ADDR, Sym: s2},
-       }
-}
-
-// assign addresses to text
-func (ctxt *Link) textaddress() {
-       addsection(ctxt.Arch, &Segtext, ".text", 05)
-
-       // Assign PCs in text segment.
-       // Could parallelize, by assigning to text
-       // and then letting threads copy down, but probably not worth it.
-       sect := Segtext.Sections[0]
-
-       sect.Align = int32(Funcalign)
-
-       text := ctxt.Syms.Lookup("runtime.text", 0)
-       text.Sect = sect
-       if ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal {
-               // Setting runtime.text has a real symbol prevents ld to
-               // change its base address resulting in wrong offsets for
-               // reflect methods.
-               text.Align = sect.Align
-               text.Size = 0x8
-       }
-
-       if (ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
-               etext := ctxt.Syms.Lookup("runtime.etext", 0)
-               etext.Sect = sect
-
-               ctxt.Textp = append(ctxt.Textp, etext, nil)
-               copy(ctxt.Textp[1:], ctxt.Textp)
-               ctxt.Textp[0] = text
-       }
-
-       va := uint64(*FlagTextAddr)
-       n := 1
-       sect.Vaddr = va
-       ntramps := 0
-       for _, s := range ctxt.Textp {
-               sect, n, va = assignAddress(ctxt, sect, n, s, va, false)
-
-               trampoline(ctxt, s) // resolve jumps, may add trampolines if jump too far
-
-               // lay down trampolines after each function
-               for ; ntramps < len(ctxt.tramps); ntramps++ {
-                       tramp := ctxt.tramps[ntramps]
-                       if ctxt.HeadType == objabi.Haix && strings.HasPrefix(tramp.Name, "runtime.text.") {
-                               // Already set in assignAddress
-                               continue
-                       }
-                       sect, n, va = assignAddress(ctxt, sect, n, tramp, va, true)
-               }
-       }
-
-       sect.Length = va - sect.Vaddr
-       ctxt.Syms.Lookup("runtime.etext", 0).Sect = sect
-
-       // merge tramps into Textp, keeping Textp in address order
-       if ntramps != 0 {
-               newtextp := make([]*sym.Symbol, 0, len(ctxt.Textp)+ntramps)
-               i := 0
-               for _, s := range ctxt.Textp {
-                       for ; i < ntramps && ctxt.tramps[i].Value < s.Value; i++ {
-                               newtextp = append(newtextp, ctxt.tramps[i])
-                       }
-                       newtextp = append(newtextp, s)
-               }
-               newtextp = append(newtextp, ctxt.tramps[i:ntramps]...)
-
-               ctxt.Textp = newtextp
-       }
-}
-
-// assigns address for a text symbol, returns (possibly new) section, its number, and the address
-// Note: once we have trampoline insertion support for external linking, this function
-// will not need to create new text sections, and so no need to return sect and n.
-func assignAddress(ctxt *Link, sect *sym.Section, n int, s *sym.Symbol, va uint64, isTramp bool) (*sym.Section, int, uint64) {
-       if thearch.AssignAddress != nil {
-               return thearch.AssignAddress(ctxt, sect, n, s, va, isTramp)
-       }
-
-       s.Sect = sect
-       if s.Attr.SubSymbol() {
-               return sect, n, va
-       }
-       if s.Align != 0 {
-               va = uint64(Rnd(int64(va), int64(s.Align)))
-       } else {
-               va = uint64(Rnd(int64(va), int64(Funcalign)))
-       }
-
-       funcsize := uint64(MINFUNC) // spacing required for findfunctab
-       if s.Size > MINFUNC {
-               funcsize = uint64(s.Size)
-       }
-
-       if sect.Align < s.Align {
-               sect.Align = s.Align
-       }
-
-       // On ppc64x a text section should not be larger than 2^26 bytes due to the size of
-       // call target offset field in the bl instruction.  Splitting into smaller text
-       // sections smaller than this limit allows the GNU linker to modify the long calls
-       // appropriately.  The limit allows for the space needed for tables inserted by the linker.
-
-       // If this function doesn't fit in the current text section, then create a new one.
-
-       // Only break at outermost syms.
-
-       if ctxt.Arch.InFamily(sys.PPC64) && s.Outer == nil && ctxt.LinkMode == LinkExternal && va-sect.Vaddr+funcsize+maxSizeTrampolinesPPC64(s, isTramp) > 0x1c00000 {
-               // Set the length for the previous text section
-               sect.Length = va - sect.Vaddr
-
-               // Create new section, set the starting Vaddr
-               sect = addsection(ctxt.Arch, &Segtext, ".text", 05)
-               sect.Vaddr = va
-               s.Sect = sect
-
-               // Create a symbol for the start of the secondary text sections
-               ntext := ctxt.Syms.Lookup(fmt.Sprintf("runtime.text.%d", n), 0)
-               ntext.Sect = sect
-               if ctxt.HeadType == objabi.Haix {
-                       // runtime.text.X must be a real symbol on AIX.
-                       // Assign its address directly in order to be the
-                       // first symbol of this new section.
-                       ntext.Type = sym.STEXT
-                       ntext.Size = int64(MINFUNC)
-                       ntext.Attr |= sym.AttrReachable
-                       ntext.Attr |= sym.AttrOnList
-                       ctxt.tramps = append(ctxt.tramps, ntext)
-
-                       ntext.Value = int64(va)
-                       va += uint64(ntext.Size)
-
-                       if s.Align != 0 {
-                               va = uint64(Rnd(int64(va), int64(s.Align)))
-                       } else {
-                               va = uint64(Rnd(int64(va), int64(Funcalign)))
-                       }
-               }
-               n++
-       }
-
-       s.Value = 0
-       for sub := s; sub != nil; sub = sub.Sub {
-               sub.Value += int64(va)
-       }
-
-       va += funcsize
-
-       return sect, n, va
-}
-
-// address assigns virtual addresses to all segments and sections and
-// returns all segments in file order.
-func (ctxt *Link) address() []*sym.Segment {
-       var order []*sym.Segment // Layout order
-
-       va := uint64(*FlagTextAddr)
-       order = append(order, &Segtext)
-       Segtext.Rwx = 05
-       Segtext.Vaddr = va
-       for _, s := range Segtext.Sections {
-               va = uint64(Rnd(int64(va), int64(s.Align)))
-               s.Vaddr = va
-               va += s.Length
-       }
-
-       Segtext.Length = va - uint64(*FlagTextAddr)
-
-       if len(Segrodata.Sections) > 0 {
-               // align to page boundary so as not to mix
-               // rodata and executable text.
-               //
-               // Note: gold or GNU ld will reduce the size of the executable
-               // file by arranging for the relro segment to end at a page
-               // boundary, and overlap the end of the text segment with the
-               // start of the relro segment in the file.  The PT_LOAD segments
-               // will be such that the last page of the text segment will be
-               // mapped twice, once r-x and once starting out rw- and, after
-               // relocation processing, changed to r--.
-               //
-               // Ideally the last page of the text segment would not be
-               // writable even for this short period.
-               va = uint64(Rnd(int64(va), int64(*FlagRound)))
-
-               order = append(order, &Segrodata)
-               Segrodata.Rwx = 04
-               Segrodata.Vaddr = va
-               for _, s := range Segrodata.Sections {
-                       va = uint64(Rnd(int64(va), int64(s.Align)))
-                       s.Vaddr = va
-                       va += s.Length
-               }
-
-               Segrodata.Length = va - Segrodata.Vaddr
-       }
-       if len(Segrelrodata.Sections) > 0 {
-               // align to page boundary so as not to mix
-               // rodata, rel-ro data, and executable text.
-               va = uint64(Rnd(int64(va), int64(*FlagRound)))
-               if ctxt.HeadType == objabi.Haix {
-                       // Relro data are inside data segment on AIX.
-                       va += uint64(XCOFFDATABASE) - uint64(XCOFFTEXTBASE)
-               }
-
-               order = append(order, &Segrelrodata)
-               Segrelrodata.Rwx = 06
-               Segrelrodata.Vaddr = va
-               for _, s := range Segrelrodata.Sections {
-                       va = uint64(Rnd(int64(va), int64(s.Align)))
-                       s.Vaddr = va
-                       va += s.Length
-               }
-
-               Segrelrodata.Length = va - Segrelrodata.Vaddr
-       }
-
-       va = uint64(Rnd(int64(va), int64(*FlagRound)))
-       if ctxt.HeadType == objabi.Haix && len(Segrelrodata.Sections) == 0 {
-               // Data sections are moved to an unreachable segment
-               // to ensure that they are position-independent.
-               // Already done if relro sections exist.
-               va += uint64(XCOFFDATABASE) - uint64(XCOFFTEXTBASE)
-       }
-       order = append(order, &Segdata)
-       Segdata.Rwx = 06
-       Segdata.Vaddr = va
-       var data *sym.Section
-       var noptr *sym.Section
-       var bss *sym.Section
-       var noptrbss *sym.Section
-       for i, s := range Segdata.Sections {
-               if (ctxt.IsELF || ctxt.HeadType == objabi.Haix) && s.Name == ".tbss" {
-                       continue
-               }
-               vlen := int64(s.Length)
-               if i+1 < len(Segdata.Sections) && !((ctxt.IsELF || ctxt.HeadType == objabi.Haix) && Segdata.Sections[i+1].Name == ".tbss") {
-                       vlen = int64(Segdata.Sections[i+1].Vaddr - s.Vaddr)
-               }
-               s.Vaddr = va
-               va += uint64(vlen)
-               Segdata.Length = va - Segdata.Vaddr
-               if s.Name == ".data" {
-                       data = s
-               }
-               if s.Name == ".noptrdata" {
-                       noptr = s
-               }
-               if s.Name == ".bss" {
-                       bss = s
-               }
-               if s.Name == ".noptrbss" {
-                       noptrbss = s
-               }
-       }
-
-       // Assign Segdata's Filelen omitting the BSS. We do this here
-       // simply because right now we know where the BSS starts.
-       Segdata.Filelen = bss.Vaddr - Segdata.Vaddr
-
-       va = uint64(Rnd(int64(va), int64(*FlagRound)))
-       order = append(order, &Segdwarf)
-       Segdwarf.Rwx = 06
-       Segdwarf.Vaddr = va
-       for i, s := range Segdwarf.Sections {
-               vlen := int64(s.Length)
-               if i+1 < len(Segdwarf.Sections) {
-                       vlen = int64(Segdwarf.Sections[i+1].Vaddr - s.Vaddr)
-               }
-               s.Vaddr = va
-               va += uint64(vlen)
-               if ctxt.HeadType == objabi.Hwindows {
-                       va = uint64(Rnd(int64(va), PEFILEALIGN))
-               }
-               Segdwarf.Length = va - Segdwarf.Vaddr
-       }
-
-       var (
-               text     = Segtext.Sections[0]
-               rodata   = ctxt.Syms.Lookup("runtime.rodata", 0).Sect
-               itablink = ctxt.Syms.Lookup("runtime.itablink", 0).Sect
-               symtab   = ctxt.Syms.Lookup("runtime.symtab", 0).Sect
-               pclntab  = ctxt.Syms.Lookup("runtime.pclntab", 0).Sect
-               types    = ctxt.Syms.Lookup("runtime.types", 0).Sect
-       )
-       lasttext := text
-       // Could be multiple .text sections
-       for _, sect := range Segtext.Sections {
-               if sect.Name == ".text" {
-                       lasttext = sect
-               }
-       }
-
-       for _, s := range datap {
-               if s.Sect != nil {
-                       s.Value += int64(s.Sect.Vaddr)
-               }
-               for sub := s.Sub; sub != nil; sub = sub.Sub {
-                       sub.Value += s.Value
-               }
-       }
-
-       for _, s := range dwarfp {
-               if s.Sect != nil {
-                       s.Value += int64(s.Sect.Vaddr)
-               }
-               for sub := s.Sub; sub != nil; sub = sub.Sub {
-                       sub.Value += s.Value
-               }
-       }
-
-       if ctxt.BuildMode == BuildModeShared {
-               s := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
-               sectSym := ctxt.Syms.Lookup(".note.go.abihash", 0)
-               s.Sect = sectSym.Sect
-               s.Value = int64(sectSym.Sect.Vaddr + 16)
-       }
-
-       ctxt.xdefine("runtime.text", sym.STEXT, int64(text.Vaddr))
-       ctxt.xdefine("runtime.etext", sym.STEXT, int64(lasttext.Vaddr+lasttext.Length))
-
-       // If there are multiple text sections, create runtime.text.n for
-       // their section Vaddr, using n for index
-       n := 1
-       for _, sect := range Segtext.Sections[1:] {
-               if sect.Name != ".text" {
-                       break
-               }
-               symname := fmt.Sprintf("runtime.text.%d", n)
-               if ctxt.HeadType != objabi.Haix || ctxt.LinkMode != LinkExternal {
-                       // Addresses are already set on AIX with external linker
-                       // because these symbols are part of their sections.
-                       ctxt.xdefine(symname, sym.STEXT, int64(sect.Vaddr))
-               }
-               n++
-       }
-
-       ctxt.xdefine("runtime.rodata", sym.SRODATA, int64(rodata.Vaddr))
-       ctxt.xdefine("runtime.erodata", sym.SRODATA, int64(rodata.Vaddr+rodata.Length))
-       ctxt.xdefine("runtime.types", sym.SRODATA, int64(types.Vaddr))
-       ctxt.xdefine("runtime.etypes", sym.SRODATA, int64(types.Vaddr+types.Length))
-       ctxt.xdefine("runtime.itablink", sym.SRODATA, int64(itablink.Vaddr))
-       ctxt.xdefine("runtime.eitablink", sym.SRODATA, int64(itablink.Vaddr+itablink.Length))
-
-       s := ctxt.Syms.Lookup("runtime.gcdata", 0)
-       s.Attr |= sym.AttrLocal
-       ctxt.xdefine("runtime.egcdata", sym.SRODATA, Symaddr(s)+s.Size)
-       ctxt.Syms.Lookup("runtime.egcdata", 0).Sect = s.Sect
-
-       s = ctxt.Syms.Lookup("runtime.gcbss", 0)
-       s.Attr |= sym.AttrLocal
-       ctxt.xdefine("runtime.egcbss", sym.SRODATA, Symaddr(s)+s.Size)
-       ctxt.Syms.Lookup("runtime.egcbss", 0).Sect = s.Sect
-
-       ctxt.xdefine("runtime.symtab", sym.SRODATA, int64(symtab.Vaddr))
-       ctxt.xdefine("runtime.esymtab", sym.SRODATA, int64(symtab.Vaddr+symtab.Length))
-       ctxt.xdefine("runtime.pclntab", sym.SRODATA, int64(pclntab.Vaddr))
-       ctxt.xdefine("runtime.epclntab", sym.SRODATA, int64(pclntab.Vaddr+pclntab.Length))
-       ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr))
-       ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr+noptr.Length))
-       ctxt.xdefine("runtime.bss", sym.SBSS, int64(bss.Vaddr))
-       ctxt.xdefine("runtime.ebss", sym.SBSS, int64(bss.Vaddr+bss.Length))
-       ctxt.xdefine("runtime.data", sym.SDATA, int64(data.Vaddr))
-       ctxt.xdefine("runtime.edata", sym.SDATA, int64(data.Vaddr+data.Length))
-       ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr))
-       ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length))
-       ctxt.xdefine("runtime.end", sym.SBSS, int64(Segdata.Vaddr+Segdata.Length))
-
-       return order
-}
-
-// layout assigns file offsets and lengths to the segments in order.
-// Returns the file size containing all the segments.
-func (ctxt *Link) layout(order []*sym.Segment) uint64 {
-       var prev *sym.Segment
-       for _, seg := range order {
-               if prev == nil {
-                       seg.Fileoff = uint64(HEADR)
-               } else {
-                       switch ctxt.HeadType {
-                       default:
-                               // Assuming the previous segment was
-                               // aligned, the following rounding
-                               // should ensure that this segment's
-                               // VA ≡ Fileoff mod FlagRound.
-                               seg.Fileoff = uint64(Rnd(int64(prev.Fileoff+prev.Filelen), int64(*FlagRound)))
-                               if seg.Vaddr%uint64(*FlagRound) != seg.Fileoff%uint64(*FlagRound) {
-                                       Exitf("bad segment rounding (Vaddr=%#x Fileoff=%#x FlagRound=%#x)", seg.Vaddr, seg.Fileoff, *FlagRound)
-                               }
-                       case objabi.Hwindows:
-                               seg.Fileoff = prev.Fileoff + uint64(Rnd(int64(prev.Filelen), PEFILEALIGN))
-                       case objabi.Hplan9:
-                               seg.Fileoff = prev.Fileoff + prev.Filelen
-                       }
-               }
-               if seg != &Segdata {
-                       // Link.address already set Segdata.Filelen to
-                       // account for BSS.
-                       seg.Filelen = seg.Length
-               }
-               prev = seg
-       }
-       return prev.Fileoff + prev.Filelen
-}
-
-// add a trampoline with symbol s (to be laid down after the current function)
-func (ctxt *Link) AddTramp(s *sym.Symbol) {
-       s.Type = sym.STEXT
-       s.Attr |= sym.AttrReachable
-       s.Attr |= sym.AttrOnList
-       ctxt.tramps = append(ctxt.tramps, s)
-       if *FlagDebugTramp > 0 && ctxt.Debugvlog > 0 {
-               ctxt.Logf("trampoline %s inserted\n", s)
-       }
-}
-
-// compressSyms compresses syms and returns the contents of the
-// compressed section. If the section would get larger, it returns nil.
-func compressSyms(ctxt *Link, syms []*sym.Symbol) []byte {
-       var total int64
-       for _, sym := range syms {
-               total += sym.Size
-       }
-
-       var buf bytes.Buffer
-       buf.Write([]byte("ZLIB"))
-       var sizeBytes [8]byte
-       binary.BigEndian.PutUint64(sizeBytes[:], uint64(total))
-       buf.Write(sizeBytes[:])
-
-       // Using zlib.BestSpeed achieves very nearly the same
-       // compression levels of zlib.DefaultCompression, but takes
-       // substantially less time. This is important because DWARF
-       // compression can be a significant fraction of link time.
-       z, err := zlib.NewWriterLevel(&buf, zlib.BestSpeed)
-       if err != nil {
-               log.Fatalf("NewWriterLevel failed: %s", err)
-       }
-       for _, s := range syms {
-               // s.P may be read-only. Apply relocations in a
-               // temporary buffer, and immediately write it out.
-               oldP := s.P
-               wasReadOnly := s.Attr.ReadOnly()
-               if len(s.R) != 0 && wasReadOnly {
-                       ctxt.relocbuf = append(ctxt.relocbuf[:0], s.P...)
-                       s.P = ctxt.relocbuf
-                       s.Attr.Set(sym.AttrReadOnly, false)
-               }
-               relocsym(ctxt, s)
-               if _, err := z.Write(s.P); err != nil {
-                       log.Fatalf("compression failed: %s", err)
-               }
-               for i := s.Size - int64(len(s.P)); i > 0; {
-                       b := zeros[:]
-                       if i < int64(len(b)) {
-                               b = b[:i]
-                       }
-                       n, err := z.Write(b)
-                       if err != nil {
-                               log.Fatalf("compression failed: %s", err)
-                       }
-                       i -= int64(n)
-               }
-               // Restore s.P if a temporary buffer was used. If compression
-               // is not beneficial, we'll go back to use the uncompressed
-               // contents, in which case we still need s.P.
-               if len(s.R) != 0 && wasReadOnly {
-                       s.P = oldP
-                       s.Attr.Set(sym.AttrReadOnly, wasReadOnly)
-                       for i := range s.R {
-                               s.R[i].Done = false
-                       }
-               }
-       }
-       if err := z.Close(); err != nil {
-               log.Fatalf("compression failed: %s", err)
-       }
-       if int64(buf.Len()) >= total {
-               // Compression didn't save any space.
-               return nil
-       }
-       return buf.Bytes()
-}
diff --git a/src/cmd/oldlink/internal/ld/deadcode.go b/src/cmd/oldlink/internal/ld/deadcode.go
deleted file mode 100644 (file)
index 6a6813a..0000000
+++ /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 (file)
index 82bfd60..0000000
+++ /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 (file)
index 0676e94..0000000
+++ /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 (file)
index 3d5220c..0000000
+++ /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 (file)
index 28cab75..0000000
+++ /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 (file)
index fe5cc40..0000000
+++ /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 (file)
index a70dea9..0000000
+++ /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 (file)
index b052655..0000000
+++ /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 (file)
index 7420dce..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-// Derived from Inferno utils/6l/obj.c and utils/6l/span.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ld
-
-import (
-       "cmd/oldlink/internal/sym"
-       "io/ioutil"
-       "log"
-       "os"
-       "path"
-       "path/filepath"
-       "strconv"
-       "strings"
-)
-
-func (ctxt *Link) readImportCfg(file string) {
-       ctxt.PackageFile = make(map[string]string)
-       ctxt.PackageShlib = make(map[string]string)
-       data, err := ioutil.ReadFile(file)
-       if err != nil {
-               log.Fatalf("-importcfg: %v", err)
-       }
-
-       for lineNum, line := range strings.Split(string(data), "\n") {
-               lineNum++ // 1-based
-               line = strings.TrimSpace(line)
-               if line == "" {
-                       continue
-               }
-               if line == "" || strings.HasPrefix(line, "#") {
-                       continue
-               }
-
-               var verb, args string
-               if i := strings.Index(line, " "); i < 0 {
-                       verb = line
-               } else {
-                       verb, args = line[:i], strings.TrimSpace(line[i+1:])
-               }
-               var before, after string
-               if i := strings.Index(args, "="); i >= 0 {
-                       before, after = args[:i], args[i+1:]
-               }
-               switch verb {
-               default:
-                       log.Fatalf("%s:%d: unknown directive %q", file, lineNum, verb)
-               case "packagefile":
-                       if before == "" || after == "" {
-                               log.Fatalf(`%s:%d: invalid packagefile: syntax is "packagefile path=filename"`, file, lineNum)
-                       }
-                       ctxt.PackageFile[before] = after
-               case "packageshlib":
-                       if before == "" || after == "" {
-                               log.Fatalf(`%s:%d: invalid packageshlib: syntax is "packageshlib path=filename"`, file, lineNum)
-                       }
-                       ctxt.PackageShlib[before] = after
-               }
-       }
-}
-
-func pkgname(ctxt *Link, lib string) string {
-       name := path.Clean(lib)
-
-       // When using importcfg, we have the final package name.
-       if ctxt.PackageFile != nil {
-               return name
-       }
-
-       // runtime.a -> runtime, runtime.6 -> runtime
-       pkg := name
-       if len(pkg) >= 2 && pkg[len(pkg)-2] == '.' {
-               pkg = pkg[:len(pkg)-2]
-       }
-       return pkg
-}
-
-func findlib(ctxt *Link, lib string) (string, bool) {
-       name := path.Clean(lib)
-
-       var pname string
-       isshlib := false
-
-       if ctxt.linkShared && ctxt.PackageShlib[name] != "" {
-               pname = ctxt.PackageShlib[name]
-               isshlib = true
-       } else if ctxt.PackageFile != nil {
-               pname = ctxt.PackageFile[name]
-               if pname == "" {
-                       ctxt.Logf("cannot find package %s (using -importcfg)\n", name)
-                       return "", false
-               }
-       } else {
-               if filepath.IsAbs(name) {
-                       pname = name
-               } else {
-                       pkg := pkgname(ctxt, lib)
-                       // Add .a if needed; the new -importcfg modes
-                       // do not put .a into the package name anymore.
-                       // This only matters when people try to mix
-                       // compiles using -importcfg with links not using -importcfg,
-                       // such as when running quick things like
-                       // 'go tool compile x.go && go tool link x.o'
-                       // by hand against a standard library built using -importcfg.
-                       if !strings.HasSuffix(name, ".a") && !strings.HasSuffix(name, ".o") {
-                               name += ".a"
-                       }
-                       // try dot, -L "libdir", and then goroot.
-                       for _, dir := range ctxt.Libdir {
-                               if ctxt.linkShared {
-                                       pname = filepath.Join(dir, pkg+".shlibname")
-                                       if _, err := os.Stat(pname); err == nil {
-                                               isshlib = true
-                                               break
-                                       }
-                               }
-                               pname = filepath.Join(dir, name)
-                               if _, err := os.Stat(pname); err == nil {
-                                       break
-                               }
-                       }
-               }
-               pname = filepath.Clean(pname)
-       }
-
-       return pname, isshlib
-}
-
-func addlib(ctxt *Link, src string, obj string, lib string) *sym.Library {
-       pkg := pkgname(ctxt, lib)
-
-       // already loaded?
-       if l := ctxt.LibraryByPkg[pkg]; l != nil {
-               return l
-       }
-
-       pname, isshlib := findlib(ctxt, lib)
-
-       if ctxt.Debugvlog > 1 {
-               ctxt.Logf("addlib: %s %s pulls in %s isshlib %v\n", obj, src, pname, isshlib)
-       }
-
-       if isshlib {
-               return addlibpath(ctxt, src, obj, "", pkg, pname)
-       }
-       return addlibpath(ctxt, src, obj, pname, pkg, "")
-}
-
-/*
- * add library to library list, return added library.
- *     srcref: src file referring to package
- *     objref: object file referring to package
- *     file: object file, e.g., /home/rsc/go/pkg/container/vector.a
- *     pkg: package import path, e.g. container/vector
- *     shlib: path to shared library, or .shlibname file holding path
- */
-func addlibpath(ctxt *Link, srcref string, objref string, file string, pkg string, shlib string) *sym.Library {
-       if l := ctxt.LibraryByPkg[pkg]; l != nil {
-               return l
-       }
-
-       if ctxt.Debugvlog > 1 {
-               ctxt.Logf("addlibpath: srcref: %s objref: %s file: %s pkg: %s shlib: %s\n", srcref, objref, file, pkg, shlib)
-       }
-
-       l := &sym.Library{}
-       ctxt.LibraryByPkg[pkg] = l
-       ctxt.Library = append(ctxt.Library, l)
-       l.Objref = objref
-       l.Srcref = srcref
-       l.File = file
-       l.Pkg = pkg
-       if shlib != "" {
-               if strings.HasSuffix(shlib, ".shlibname") {
-                       data, err := ioutil.ReadFile(shlib)
-                       if err != nil {
-                               Errorf(nil, "cannot read %s: %v", shlib, err)
-                       }
-                       shlib = strings.TrimSpace(string(data))
-               }
-               l.Shlib = shlib
-       }
-       return l
-}
-
-func atolwhex(s string) int64 {
-       n, _ := strconv.ParseInt(s, 0, 64)
-       return n
-}
diff --git a/src/cmd/oldlink/internal/ld/lib.go b/src/cmd/oldlink/internal/ld/lib.go
deleted file mode 100644 (file)
index 0fc786f..0000000
+++ /dev/null
@@ -1,2749 +0,0 @@
-// Inferno utils/8l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/8l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ld
-
-import (
-       "bufio"
-       "bytes"
-       "cmd/internal/bio"
-       "cmd/internal/obj"
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/loadelf"
-       "cmd/oldlink/internal/loader"
-       "cmd/oldlink/internal/loadmacho"
-       "cmd/oldlink/internal/loadpe"
-       "cmd/oldlink/internal/loadxcoff"
-       "cmd/oldlink/internal/objfile"
-       "cmd/oldlink/internal/sym"
-       "crypto/sha1"
-       "debug/elf"
-       "debug/macho"
-       "encoding/base64"
-       "encoding/binary"
-       "encoding/hex"
-       "fmt"
-       "io"
-       "io/ioutil"
-       "log"
-       "os"
-       "os/exec"
-       "path/filepath"
-       "runtime"
-       "sort"
-       "strings"
-       "sync"
-)
-
-// Data layout and relocation.
-
-// Derived from Inferno utils/6l/l.h
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-type Arch struct {
-       Funcalign      int
-       Maxalign       int
-       Minalign       int
-       Dwarfregsp     int
-       Dwarfreglr     int
-       Androiddynld   string
-       Linuxdynld     string
-       Freebsddynld   string
-       Netbsddynld    string
-       Openbsddynld   string
-       Dragonflydynld string
-       Solarisdynld   string
-       Adddynrel      func(*Link, *sym.Symbol, *sym.Reloc) bool
-       Archinit       func(*Link)
-       // Archreloc is an arch-specific hook that assists in
-       // relocation processing (invoked by 'relocsym'); it handles
-       // target-specific relocation tasks. Here "rel" is the current
-       // relocation being examined, "sym" is the symbol containing the
-       // chunk of data to which the relocation applies, and "off" is the
-       // contents of the to-be-relocated data item (from sym.P). Return
-       // value is the appropriately relocated value (to be written back
-       // to the same spot in sym.P) and a boolean indicating
-       // success/failure (a failing value indicates a fatal error).
-       Archreloc func(link *Link, rel *sym.Reloc, sym *sym.Symbol,
-               offset int64) (relocatedOffset int64, success bool)
-       // Archrelocvariant is a second arch-specific hook used for
-       // relocation processing; it handles relocations where r.Type is
-       // insufficient to describe the relocation (r.Variant !=
-       // sym.RV_NONE). Here "rel" is the relocation being applied, "sym"
-       // is the symbol containing the chunk of data to which the
-       // relocation applies, and "off" is the contents of the
-       // to-be-relocated data item (from sym.P). Return is an updated
-       // offset value.
-       Archrelocvariant func(link *Link, rel *sym.Reloc, sym *sym.Symbol,
-               offset int64) (relocatedOffset int64)
-       Trampoline func(*Link, *sym.Reloc, *sym.Symbol)
-
-       // Asmb and Asmb2 are arch-specific routines that write the output
-       // file. Typically, Asmb writes most of the content (sections and
-       // segments), for which we have computed the size and offset. Asmb2
-       // writes the rest.
-       Asmb  func(*Link)
-       Asmb2 func(*Link)
-
-       Elfreloc1   func(*Link, *sym.Reloc, int64) bool
-       Elfsetupplt func(*Link)
-       Gentext     func(*Link)
-       Machoreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
-       PEreloc1    func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
-       Xcoffreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
-
-       // TLSIEtoLE converts a TLS Initial Executable relocation to
-       // a TLS Local Executable relocation.
-       //
-       // This is possible when a TLS IE relocation refers to a local
-       // symbol in an executable, which is typical when internally
-       // linking PIE binaries.
-       TLSIEtoLE func(s *sym.Symbol, off, size int)
-
-       // optional override for assignAddress
-       AssignAddress func(ctxt *Link, sect *sym.Section, n int, s *sym.Symbol, va uint64, isTramp bool) (*sym.Section, int, uint64)
-}
-
-var (
-       thearch Arch
-       Lcsize  int32
-       rpath   Rpath
-       Spsize  int32
-       Symsize int32
-)
-
-const (
-       MINFUNC = 16 // minimum size for a function
-)
-
-// DynlinkingGo reports whether we are producing Go code that can live
-// in separate shared libraries linked together at runtime.
-func (ctxt *Link) DynlinkingGo() bool {
-       if !ctxt.Loaded {
-               panic("DynlinkingGo called before all symbols loaded")
-       }
-       return ctxt.BuildMode == BuildModeShared || ctxt.linkShared || ctxt.BuildMode == BuildModePlugin || ctxt.canUsePlugins
-}
-
-// CanUsePlugins reports whether a plugins can be used
-func (ctxt *Link) CanUsePlugins() bool {
-       if !ctxt.Loaded {
-               panic("CanUsePlugins called before all symbols loaded")
-       }
-       return ctxt.canUsePlugins
-}
-
-// UseRelro reports whether to make use of "read only relocations" aka
-// relro.
-func (ctxt *Link) UseRelro() bool {
-       switch ctxt.BuildMode {
-       case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePIE, BuildModePlugin:
-               return ctxt.IsELF || ctxt.HeadType == objabi.Haix
-       default:
-               return ctxt.linkShared || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal)
-       }
-}
-
-var (
-       dynexp          []*sym.Symbol
-       dynlib          []string
-       ldflag          []string
-       havedynamic     int
-       Funcalign       int
-       iscgo           bool
-       elfglobalsymndx int
-       interpreter     string
-
-       debug_s bool // backup old value of debug['s']
-       HEADR   int32
-
-       nerrors  int
-       liveness int64
-
-       // See -strictdups command line flag.
-       checkStrictDups   int // 0=off 1=warning 2=error
-       strictDupMsgCount int
-)
-
-var (
-       Segtext      sym.Segment
-       Segrodata    sym.Segment
-       Segrelrodata sym.Segment
-       Segdata      sym.Segment
-       Segdwarf     sym.Segment
-)
-
-const pkgdef = "__.PKGDEF"
-
-var (
-       // Set if we see an object compiled by the host compiler that is not
-       // from a package that is known to support internal linking mode.
-       externalobj = false
-       theline     string
-)
-
-func Lflag(ctxt *Link, arg string) {
-       ctxt.Libdir = append(ctxt.Libdir, arg)
-}
-
-/*
- * Unix doesn't like it when we write to a running (or, sometimes,
- * recently run) binary, so remove the output file before writing it.
- * On Windows 7, remove() can force a subsequent create() to fail.
- * S_ISREG() does not exist on Plan 9.
- */
-func mayberemoveoutfile() {
-       if fi, err := os.Lstat(*flagOutfile); err == nil && !fi.Mode().IsRegular() {
-               return
-       }
-       os.Remove(*flagOutfile)
-}
-
-func libinit(ctxt *Link) {
-       Funcalign = thearch.Funcalign
-
-       // add goroot to the end of the libdir list.
-       suffix := ""
-
-       suffixsep := ""
-       if *flagInstallSuffix != "" {
-               suffixsep = "_"
-               suffix = *flagInstallSuffix
-       } else if *flagRace {
-               suffixsep = "_"
-               suffix = "race"
-       } else if *flagMsan {
-               suffixsep = "_"
-               suffix = "msan"
-       }
-
-       Lflag(ctxt, filepath.Join(objabi.GOROOT, "pkg", fmt.Sprintf("%s_%s%s%s", objabi.GOOS, objabi.GOARCH, suffixsep, suffix)))
-
-       mayberemoveoutfile()
-       f, err := os.OpenFile(*flagOutfile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775)
-       if err != nil {
-               Exitf("cannot create %s: %v", *flagOutfile, err)
-       }
-
-       ctxt.Out.w = bufio.NewWriter(f)
-       ctxt.Out.f = f
-
-       if *flagEntrySymbol == "" {
-               switch ctxt.BuildMode {
-               case BuildModeCShared, BuildModeCArchive:
-                       *flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s_lib", objabi.GOARCH, objabi.GOOS)
-               case BuildModeExe, BuildModePIE:
-                       *flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s", objabi.GOARCH, objabi.GOOS)
-               case BuildModeShared, BuildModePlugin:
-                       // No *flagEntrySymbol for -buildmode=shared and plugin
-               default:
-                       Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", ctxt.BuildMode)
-               }
-       }
-}
-
-func exitIfErrors() {
-       if nerrors != 0 || checkStrictDups > 1 && strictDupMsgCount > 0 {
-               mayberemoveoutfile()
-               Exit(2)
-       }
-
-}
-
-func errorexit() {
-       exitIfErrors()
-       Exit(0)
-}
-
-func loadinternal(ctxt *Link, name string) *sym.Library {
-       if ctxt.linkShared && ctxt.PackageShlib != nil {
-               if shlib := ctxt.PackageShlib[name]; shlib != "" {
-                       return addlibpath(ctxt, "internal", "internal", "", name, shlib)
-               }
-       }
-       if ctxt.PackageFile != nil {
-               if pname := ctxt.PackageFile[name]; pname != "" {
-                       return addlibpath(ctxt, "internal", "internal", pname, name, "")
-               }
-               ctxt.Logf("loadinternal: cannot find %s\n", name)
-               return nil
-       }
-
-       for _, libdir := range ctxt.Libdir {
-               if ctxt.linkShared {
-                       shlibname := filepath.Join(libdir, name+".shlibname")
-                       if ctxt.Debugvlog != 0 {
-                               ctxt.Logf("searching for %s.a in %s\n", name, shlibname)
-                       }
-                       if _, err := os.Stat(shlibname); err == nil {
-                               return addlibpath(ctxt, "internal", "internal", "", name, shlibname)
-                       }
-               }
-               pname := filepath.Join(libdir, name+".a")
-               if ctxt.Debugvlog != 0 {
-                       ctxt.Logf("searching for %s.a in %s\n", name, pname)
-               }
-               if _, err := os.Stat(pname); err == nil {
-                       return addlibpath(ctxt, "internal", "internal", pname, name, "")
-               }
-       }
-
-       ctxt.Logf("warning: unable to find %s.a\n", name)
-       return nil
-}
-
-// extld returns the current external linker.
-func (ctxt *Link) extld() string {
-       if *flagExtld == "" {
-               *flagExtld = "gcc"
-       }
-       return *flagExtld
-}
-
-// findLibPathCmd uses cmd command to find gcc library libname.
-// It returns library full path if found, or "none" if not found.
-func (ctxt *Link) findLibPathCmd(cmd, libname string) string {
-       extld := ctxt.extld()
-       args := hostlinkArchArgs(ctxt.Arch)
-       args = append(args, cmd)
-       if ctxt.Debugvlog != 0 {
-               ctxt.Logf("%s %v\n", extld, args)
-       }
-       out, err := exec.Command(extld, args...).Output()
-       if err != nil {
-               if ctxt.Debugvlog != 0 {
-                       ctxt.Logf("not using a %s file because compiler failed\n%v\n%s\n", libname, err, out)
-               }
-               return "none"
-       }
-       return strings.TrimSpace(string(out))
-}
-
-// findLibPath searches for library libname.
-// It returns library full path if found, or "none" if not found.
-func (ctxt *Link) findLibPath(libname string) string {
-       return ctxt.findLibPathCmd("--print-file-name="+libname, libname)
-}
-
-func (ctxt *Link) loadlib() {
-       if *flagNewobj {
-               var flags uint32
-               switch *FlagStrictDups {
-               case 0:
-                       // nothing to do
-               case 1, 2:
-                       flags = loader.FlagStrictDups
-               default:
-                       log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups)
-               }
-               ctxt.loader = loader.NewLoader(flags)
-       }
-
-       ctxt.cgo_export_static = make(map[string]bool)
-       ctxt.cgo_export_dynamic = make(map[string]bool)
-
-       // ctxt.Library grows during the loop, so not a range loop.
-       i := 0
-       for ; i < len(ctxt.Library); i++ {
-               lib := ctxt.Library[i]
-               if lib.Shlib == "" {
-                       if ctxt.Debugvlog > 1 {
-                               ctxt.Logf("autolib: %s (from %s)\n", lib.File, lib.Objref)
-                       }
-                       loadobjfile(ctxt, lib)
-               }
-       }
-
-       // load internal packages, if not already
-       if *flagRace {
-               loadinternal(ctxt, "runtime/race")
-       }
-       if *flagMsan {
-               loadinternal(ctxt, "runtime/msan")
-       }
-       loadinternal(ctxt, "runtime")
-       for ; i < len(ctxt.Library); i++ {
-               lib := ctxt.Library[i]
-               if lib.Shlib == "" {
-                       loadobjfile(ctxt, lib)
-               }
-       }
-
-       if *flagNewobj {
-               iscgo = ctxt.loader.Lookup("x_cgo_init", 0) != 0
-               ctxt.canUsePlugins = ctxt.loader.Lookup("plugin.Open", sym.SymVerABIInternal) != 0
-       } else {
-               iscgo = ctxt.Syms.ROLookup("x_cgo_init", 0) != nil
-               ctxt.canUsePlugins = ctxt.Syms.ROLookup("plugin.Open", sym.SymVerABIInternal) != nil
-       }
-
-       // We now have enough information to determine the link mode.
-       determineLinkMode(ctxt)
-
-       if ctxt.LinkMode == LinkExternal && !iscgo && ctxt.LibraryByPkg["runtime/cgo"] == nil && !(objabi.GOOS == "darwin" && ctxt.BuildMode != BuildModePlugin && ctxt.Arch.Family == sys.AMD64) {
-               // This indicates a user requested -linkmode=external.
-               // The startup code uses an import of runtime/cgo to decide
-               // whether to initialize the TLS.  So give it one. This could
-               // be handled differently but it's an unusual case.
-               if lib := loadinternal(ctxt, "runtime/cgo"); lib != nil {
-                       if lib.Shlib != "" {
-                               ldshlibsyms(ctxt, lib.Shlib)
-                       } else {
-                               if ctxt.BuildMode == BuildModeShared || ctxt.linkShared {
-                                       Exitf("cannot implicitly include runtime/cgo in a shared library")
-                               }
-                               loadobjfile(ctxt, lib)
-                       }
-               }
-       }
-
-       for _, lib := range ctxt.Library {
-               if lib.Shlib != "" {
-                       if ctxt.Debugvlog > 1 {
-                               ctxt.Logf("autolib: %s (from %s)\n", lib.Shlib, lib.Objref)
-                       }
-                       ldshlibsyms(ctxt, lib.Shlib)
-               }
-       }
-
-       if ctxt.LinkMode == LinkInternal && len(hostobj) != 0 {
-               if *flagNewobj {
-                       // In newobj mode, we typically create sym.Symbols later therefore
-                       // also set cgo attributes later. However, for internal cgo linking,
-                       // the host object loaders still work with sym.Symbols (for now),
-                       // and they need cgo attributes set to work properly. So process
-                       // them now.
-                       lookup := func(name string, ver int) *sym.Symbol { return ctxt.loader.LookupOrCreate(name, ver, ctxt.Syms) }
-                       for _, d := range ctxt.cgodata {
-                               setCgoAttr(ctxt, lookup, d.file, d.pkg, d.directives)
-                       }
-                       ctxt.cgodata = nil
-               }
-
-               // Drop all the cgo_import_static declarations.
-               // Turns out we won't be needing them.
-               for _, s := range ctxt.Syms.Allsym {
-                       if s.Type == sym.SHOSTOBJ {
-                               // If a symbol was marked both
-                               // cgo_import_static and cgo_import_dynamic,
-                               // then we want to make it cgo_import_dynamic
-                               // now.
-                               if s.Extname() != "" && s.Dynimplib() != "" && !s.Attr.CgoExport() {
-                                       s.Type = sym.SDYNIMPORT
-                               } else {
-                                       s.Type = 0
-                               }
-                       }
-               }
-       }
-
-       // Conditionally load host objects, or setup for external linking.
-       hostobjs(ctxt)
-       hostlinksetup(ctxt)
-
-       if *flagNewobj {
-               // Add references of externally defined symbols.
-               ctxt.loader.LoadRefs(ctxt.Arch, ctxt.Syms)
-       }
-
-       // Now that we know the link mode, set the dynexp list.
-       if !*flagNewobj { // set this later in newobj mode
-               setupdynexp(ctxt)
-       }
-
-       if ctxt.LinkMode == LinkInternal && len(hostobj) != 0 {
-               // If we have any undefined symbols in external
-               // objects, try to read them from the libgcc file.
-               any := false
-               for _, s := range ctxt.Syms.Allsym {
-                       for i := range s.R {
-                               r := &s.R[i] // Copying sym.Reloc has measurable impact on performance
-                               if r.Sym != nil && r.Sym.Type == sym.SXREF && r.Sym.Name != ".got" {
-                                       any = true
-                                       break
-                               }
-                       }
-               }
-               if any {
-                       if *flagLibGCC == "" {
-                               *flagLibGCC = ctxt.findLibPathCmd("--print-libgcc-file-name", "libgcc")
-                       }
-                       if runtime.GOOS == "openbsd" && *flagLibGCC == "libgcc.a" {
-                               // On OpenBSD `clang --print-libgcc-file-name` returns "libgcc.a".
-                               // In this case we fail to load libgcc.a and can encounter link
-                               // errors - see if we can find libcompiler_rt.a instead.
-                               *flagLibGCC = ctxt.findLibPathCmd("--print-file-name=libcompiler_rt.a", "libcompiler_rt")
-                       }
-                       if *flagLibGCC != "none" {
-                               hostArchive(ctxt, *flagLibGCC)
-                       }
-                       if ctxt.HeadType == objabi.Hwindows {
-                               if p := ctxt.findLibPath("libmingwex.a"); p != "none" {
-                                       hostArchive(ctxt, p)
-                               }
-                               if p := ctxt.findLibPath("libmingw32.a"); p != "none" {
-                                       hostArchive(ctxt, p)
-                               }
-                               // Link libmsvcrt.a to resolve '__acrt_iob_func' symbol
-                               // (see https://golang.org/issue/23649 for details).
-                               if p := ctxt.findLibPath("libmsvcrt.a"); p != "none" {
-                                       hostArchive(ctxt, p)
-                               }
-                               // TODO: maybe do something similar to peimporteddlls to collect all lib names
-                               // and try link them all to final exe just like libmingwex.a and libmingw32.a:
-                               /*
-                                       for:
-                                       #cgo windows LDFLAGS: -lmsvcrt -lm
-                                       import:
-                                       libmsvcrt.a libm.a
-                               */
-                       }
-               }
-       }
-
-       // We've loaded all the code now.
-       ctxt.Loaded = true
-
-       importcycles()
-
-       if *flagNewobj {
-               strictDupMsgCount = ctxt.loader.NStrictDupMsgs()
-       }
-}
-
-// Set up dynexp list.
-func setupdynexp(ctxt *Link) {
-       dynexpMap := ctxt.cgo_export_dynamic
-       if ctxt.LinkMode == LinkExternal {
-               dynexpMap = ctxt.cgo_export_static
-       }
-       dynexp = make([]*sym.Symbol, 0, len(dynexpMap))
-       for exp := range dynexpMap {
-               s := ctxt.Syms.Lookup(exp, 0)
-               dynexp = append(dynexp, s)
-       }
-       sort.Sort(byName(dynexp))
-
-       // Resolve ABI aliases in the list of cgo-exported functions.
-       // This is necessary because we load the ABI0 symbol for all
-       // cgo exports.
-       for i, s := range dynexp {
-               if s.Type != sym.SABIALIAS {
-                       continue
-               }
-               t := resolveABIAlias(s)
-               t.Attr |= s.Attr
-               t.SetExtname(s.Extname())
-               dynexp[i] = t
-       }
-
-       ctxt.cgo_export_static = nil
-       ctxt.cgo_export_dynamic = nil
-}
-
-// Set up flags and special symbols depending on the platform build mode.
-func (ctxt *Link) linksetup() {
-       switch ctxt.BuildMode {
-       case BuildModeCShared, BuildModePlugin:
-               s := ctxt.Syms.Lookup("runtime.islibrary", 0)
-               s.Type = sym.SNOPTRDATA
-               s.Attr |= sym.AttrDuplicateOK
-               s.AddUint8(1)
-       case BuildModeCArchive:
-               s := ctxt.Syms.Lookup("runtime.isarchive", 0)
-               s.Type = sym.SNOPTRDATA
-               s.Attr |= sym.AttrDuplicateOK
-               s.AddUint8(1)
-       }
-
-       // Recalculate pe parameters now that we have ctxt.LinkMode set.
-       if ctxt.HeadType == objabi.Hwindows {
-               Peinit(ctxt)
-       }
-
-       if ctxt.HeadType == objabi.Hdarwin && ctxt.LinkMode == LinkExternal {
-               *FlagTextAddr = 0
-       }
-
-       // If there are no dynamic libraries needed, gcc disables dynamic linking.
-       // Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13)
-       // assumes that a dynamic binary always refers to at least one dynamic library.
-       // Rather than be a source of test cases for glibc, disable dynamic linking
-       // the same way that gcc would.
-       //
-       // Exception: on OS X, programs such as Shark only work with dynamic
-       // binaries, so leave it enabled on OS X (Mach-O) binaries.
-       // Also leave it enabled on Solaris which doesn't support
-       // statically linked binaries.
-       if ctxt.BuildMode == BuildModeExe {
-               if havedynamic == 0 && ctxt.HeadType != objabi.Hdarwin && ctxt.HeadType != objabi.Hsolaris {
-                       *FlagD = true
-               }
-       }
-
-       if ctxt.LinkMode == LinkExternal && ctxt.Arch.Family == sys.PPC64 && objabi.GOOS != "aix" {
-               toc := ctxt.Syms.Lookup(".TOC.", 0)
-               toc.Type = sym.SDYNIMPORT
-       }
-
-       // The Android Q linker started to complain about underalignment of the our TLS
-       // section. We don't actually use the section on android, so dont't
-       // generate it.
-       if objabi.GOOS != "android" {
-               tlsg := ctxt.Syms.Lookup("runtime.tlsg", 0)
-
-               // runtime.tlsg is used for external linking on platforms that do not define
-               // a variable to hold g in assembly (currently only intel).
-               if tlsg.Type == 0 {
-                       tlsg.Type = sym.STLSBSS
-                       tlsg.Size = int64(ctxt.Arch.PtrSize)
-               } else if tlsg.Type != sym.SDYNIMPORT {
-                       Errorf(nil, "runtime declared tlsg variable %v", tlsg.Type)
-               }
-               tlsg.Attr |= sym.AttrReachable
-               ctxt.Tlsg = tlsg
-       }
-
-       var moduledata *sym.Symbol
-       if ctxt.BuildMode == BuildModePlugin {
-               moduledata = ctxt.Syms.Lookup("local.pluginmoduledata", 0)
-               moduledata.Attr |= sym.AttrLocal
-       } else {
-               moduledata = ctxt.Syms.Lookup("runtime.firstmoduledata", 0)
-       }
-       if moduledata.Type != 0 && moduledata.Type != sym.SDYNIMPORT {
-               // If the module (toolchain-speak for "executable or shared
-               // library") we are linking contains the runtime package, it
-               // will define the runtime.firstmoduledata symbol and we
-               // truncate it back to 0 bytes so we can define its entire
-               // contents in symtab.go:symtab().
-               moduledata.Size = 0
-
-               // In addition, on ARM, the runtime depends on the linker
-               // recording the value of GOARM.
-               if ctxt.Arch.Family == sys.ARM {
-                       s := ctxt.Syms.Lookup("runtime.goarm", 0)
-                       s.Type = sym.SDATA
-                       s.Size = 0
-                       s.AddUint8(uint8(objabi.GOARM))
-               }
-
-               if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
-                       s := ctxt.Syms.Lookup("runtime.framepointer_enabled", 0)
-                       s.Type = sym.SDATA
-                       s.Size = 0
-                       s.AddUint8(1)
-               }
-       } else {
-               // If OTOH the module does not contain the runtime package,
-               // create a local symbol for the moduledata.
-               moduledata = ctxt.Syms.Lookup("local.moduledata", 0)
-               moduledata.Attr |= sym.AttrLocal
-       }
-       // In all cases way we mark the moduledata as noptrdata to hide it from
-       // the GC.
-       moduledata.Type = sym.SNOPTRDATA
-       moduledata.Attr |= sym.AttrReachable
-       ctxt.Moduledata = moduledata
-
-       // If package versioning is required, generate a hash of the
-       // packages used in the link.
-       if ctxt.BuildMode == BuildModeShared || ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
-               for _, lib := range ctxt.Library {
-                       if lib.Shlib == "" {
-                               genhash(ctxt, lib)
-                       }
-               }
-       }
-
-       if ctxt.Arch == sys.Arch386 && ctxt.HeadType != objabi.Hwindows {
-               if (ctxt.BuildMode == BuildModeCArchive && ctxt.IsELF) || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE || ctxt.DynlinkingGo() {
-                       got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
-                       got.Type = sym.SDYNIMPORT
-                       got.Attr |= sym.AttrReachable
-               }
-       }
-}
-
-// mangleTypeSym shortens the names of symbols that represent Go types
-// if they are visible in the symbol table.
-//
-// As the names of these symbols are derived from the string of
-// the type, they can run to many kilobytes long. So we shorten
-// them using a SHA-1 when the name appears in the final binary.
-// This also removes characters that upset external linkers.
-//
-// These are the symbols that begin with the prefix 'type.' and
-// contain run-time type information used by the runtime and reflect
-// packages. All Go binaries contain these symbols, but only
-// those programs loaded dynamically in multiple parts need these
-// symbols to have entries in the symbol table.
-func (ctxt *Link) mangleTypeSym() {
-       if ctxt.BuildMode != BuildModeShared && !ctxt.linkShared && ctxt.BuildMode != BuildModePlugin && !ctxt.CanUsePlugins() {
-               return
-       }
-
-       for _, s := range ctxt.Syms.Allsym {
-               newName := typeSymbolMangle(s.Name)
-               if newName != s.Name {
-                       ctxt.Syms.Rename(s.Name, newName, int(s.Version), ctxt.Reachparent)
-               }
-       }
-}
-
-// typeSymbolMangle mangles the given symbol name into something shorter.
-//
-// Keep the type.. prefix, which parts of the linker (like the
-// DWARF generator) know means the symbol is not decodable.
-// Leave type.runtime. symbols alone, because other parts of
-// the linker manipulates them.
-func typeSymbolMangle(name string) string {
-       if !strings.HasPrefix(name, "type.") {
-               return name
-       }
-       if strings.HasPrefix(name, "type.runtime.") {
-               return name
-       }
-       if len(name) <= 14 && !strings.Contains(name, "@") { // Issue 19529
-               return name
-       }
-       hash := sha1.Sum([]byte(name))
-       prefix := "type."
-       if name[5] == '.' {
-               prefix = "type.."
-       }
-       return prefix + base64.StdEncoding.EncodeToString(hash[:6])
-}
-
-/*
- * look for the next file in an archive.
- * adapted from libmach.
- */
-func nextar(bp *bio.Reader, off int64, a *ArHdr) int64 {
-       if off&1 != 0 {
-               off++
-       }
-       bp.MustSeek(off, 0)
-       var buf [SAR_HDR]byte
-       if n, err := io.ReadFull(bp, buf[:]); err != nil {
-               if n == 0 && err != io.EOF {
-                       return -1
-               }
-               return 0
-       }
-
-       a.name = artrim(buf[0:16])
-       a.date = artrim(buf[16:28])
-       a.uid = artrim(buf[28:34])
-       a.gid = artrim(buf[34:40])
-       a.mode = artrim(buf[40:48])
-       a.size = artrim(buf[48:58])
-       a.fmag = artrim(buf[58:60])
-
-       arsize := atolwhex(a.size)
-       if arsize&1 != 0 {
-               arsize++
-       }
-       return arsize + SAR_HDR
-}
-
-func genhash(ctxt *Link, lib *sym.Library) {
-       f, err := bio.Open(lib.File)
-       if err != nil {
-               Errorf(nil, "cannot open file %s for hash generation: %v", lib.File, err)
-               return
-       }
-       defer f.Close()
-
-       var magbuf [len(ARMAG)]byte
-       if _, err := io.ReadFull(f, magbuf[:]); err != nil {
-               Exitf("file %s too short", lib.File)
-       }
-
-       if string(magbuf[:]) != ARMAG {
-               Exitf("%s is not an archive file", lib.File)
-       }
-
-       var arhdr ArHdr
-       l := nextar(f, f.Offset(), &arhdr)
-       if l <= 0 {
-               Errorf(nil, "%s: short read on archive file symbol header", lib.File)
-               return
-       }
-       if arhdr.name != pkgdef {
-               Errorf(nil, "%s: missing package data entry", lib.File)
-               return
-       }
-
-       h := sha1.New()
-
-       // To compute the hash of a package, we hash the first line of
-       // __.PKGDEF (which contains the toolchain version and any
-       // GOEXPERIMENT flags) and the export data (which is between
-       // the first two occurrences of "\n$$").
-
-       pkgDefBytes := make([]byte, atolwhex(arhdr.size))
-       _, err = io.ReadFull(f, pkgDefBytes)
-       if err != nil {
-               Errorf(nil, "%s: error reading package data: %v", lib.File, err)
-               return
-       }
-       firstEOL := bytes.IndexByte(pkgDefBytes, '\n')
-       if firstEOL < 0 {
-               Errorf(nil, "cannot parse package data of %s for hash generation, no newline found", lib.File)
-               return
-       }
-       firstDoubleDollar := bytes.Index(pkgDefBytes, []byte("\n$$"))
-       if firstDoubleDollar < 0 {
-               Errorf(nil, "cannot parse package data of %s for hash generation, no \\n$$ found", lib.File)
-               return
-       }
-       secondDoubleDollar := bytes.Index(pkgDefBytes[firstDoubleDollar+1:], []byte("\n$$"))
-       if secondDoubleDollar < 0 {
-               Errorf(nil, "cannot parse package data of %s for hash generation, only one \\n$$ found", lib.File)
-               return
-       }
-       h.Write(pkgDefBytes[0:firstEOL])
-       h.Write(pkgDefBytes[firstDoubleDollar : firstDoubleDollar+secondDoubleDollar])
-       lib.Hash = hex.EncodeToString(h.Sum(nil))
-}
-
-func loadobjfile(ctxt *Link, lib *sym.Library) {
-       pkg := objabi.PathToPrefix(lib.Pkg)
-
-       if ctxt.Debugvlog > 1 {
-               ctxt.Logf("ldobj: %s (%s)\n", lib.File, pkg)
-       }
-       f, err := bio.Open(lib.File)
-       if err != nil {
-               Exitf("cannot open file %s: %v", lib.File, err)
-       }
-       defer f.Close()
-       defer func() {
-               if pkg == "main" && !lib.Main {
-                       Exitf("%s: not package main", lib.File)
-               }
-
-               // Ideally, we'd check that *all* object files within
-               // the archive were marked safe, but here we settle
-               // for *any*.
-               //
-               // Historically, cmd/link only checked the __.PKGDEF
-               // file, which in turn came from the first object
-               // file, typically produced by cmd/compile. The
-               // remaining object files are normally produced by
-               // cmd/asm, which doesn't support marking files as
-               // safe anyway. So at least in practice, this matches
-               // how safe mode has always worked.
-               if *flagU && !lib.Safe {
-                       Exitf("%s: load of unsafe package %s", lib.File, pkg)
-               }
-       }()
-
-       for i := 0; i < len(ARMAG); i++ {
-               if c, err := f.ReadByte(); err == nil && c == ARMAG[i] {
-                       continue
-               }
-
-               /* load it as a regular file */
-               l := f.MustSeek(0, 2)
-               f.MustSeek(0, 0)
-               ldobj(ctxt, f, lib, l, lib.File, lib.File)
-               return
-       }
-
-       /*
-        * load all the object files from the archive now.
-        * this gives us sequential file access and keeps us
-        * from needing to come back later to pick up more
-        * objects.  it breaks the usual C archive model, but
-        * this is Go, not C.  the common case in Go is that
-        * we need to load all the objects, and then we throw away
-        * the individual symbols that are unused.
-        *
-        * loading every object will also make it possible to
-        * load foreign objects not referenced by __.PKGDEF.
-        */
-       var arhdr ArHdr
-       off := f.Offset()
-       for {
-               l := nextar(f, off, &arhdr)
-               if l == 0 {
-                       break
-               }
-               if l < 0 {
-                       Exitf("%s: malformed archive", lib.File)
-               }
-               off += l
-
-               // __.PKGDEF isn't a real Go object file, and it's
-               // absent in -linkobj builds anyway. Skipping it
-               // ensures consistency between -linkobj and normal
-               // build modes.
-               if arhdr.name == pkgdef {
-                       continue
-               }
-
-               // Skip other special (non-object-file) sections that
-               // build tools may have added. Such sections must have
-               // short names so that the suffix is not truncated.
-               if len(arhdr.name) < 16 {
-                       if ext := filepath.Ext(arhdr.name); ext != ".o" && ext != ".syso" {
-                               continue
-                       }
-               }
-
-               pname := fmt.Sprintf("%s(%s)", lib.File, arhdr.name)
-               l = atolwhex(arhdr.size)
-               ldobj(ctxt, f, lib, l, pname, lib.File)
-       }
-}
-
-type Hostobj struct {
-       ld     func(*Link, *bio.Reader, string, int64, string)
-       pkg    string
-       pn     string
-       file   string
-       off    int64
-       length int64
-}
-
-var hostobj []Hostobj
-
-// These packages can use internal linking mode.
-// Others trigger external mode.
-var internalpkg = []string{
-       "crypto/x509",
-       "net",
-       "os/user",
-       "runtime/cgo",
-       "runtime/race",
-       "runtime/msan",
-}
-
-func ldhostobj(ld func(*Link, *bio.Reader, string, int64, string), headType objabi.HeadType, f *bio.Reader, pkg string, length int64, pn string, file string) *Hostobj {
-       isinternal := false
-       for _, intpkg := range internalpkg {
-               if pkg == intpkg {
-                       isinternal = true
-                       break
-               }
-       }
-
-       // DragonFly declares errno with __thread, which results in a symbol
-       // type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not
-       // currently know how to handle TLS relocations, hence we have to
-       // force external linking for any libraries that link in code that
-       // uses errno. This can be removed if the Go linker ever supports
-       // these relocation types.
-       if headType == objabi.Hdragonfly {
-               if pkg == "net" || pkg == "os/user" {
-                       isinternal = false
-               }
-       }
-
-       if !isinternal {
-               externalobj = true
-       }
-
-       hostobj = append(hostobj, Hostobj{})
-       h := &hostobj[len(hostobj)-1]
-       h.ld = ld
-       h.pkg = pkg
-       h.pn = pn
-       h.file = file
-       h.off = f.Offset()
-       h.length = length
-       return h
-}
-
-func hostobjs(ctxt *Link) {
-       if ctxt.LinkMode != LinkInternal {
-               return
-       }
-       var h *Hostobj
-
-       for i := 0; i < len(hostobj); i++ {
-               h = &hostobj[i]
-               f, err := bio.Open(h.file)
-               if err != nil {
-                       Exitf("cannot reopen %s: %v", h.pn, err)
-               }
-
-               f.MustSeek(h.off, 0)
-               h.ld(ctxt, f, h.pkg, h.length, h.pn)
-               f.Close()
-       }
-}
-
-func hostlinksetup(ctxt *Link) {
-       if ctxt.LinkMode != LinkExternal {
-               return
-       }
-
-       // For external link, record that we need to tell the external linker -s,
-       // and turn off -s internally: the external linker needs the symbol
-       // information for its final link.
-       debug_s = *FlagS
-       *FlagS = false
-
-       // create temporary directory and arrange cleanup
-       if *flagTmpdir == "" {
-               dir, err := ioutil.TempDir("", "go-link-")
-               if err != nil {
-                       log.Fatal(err)
-               }
-               *flagTmpdir = dir
-               ownTmpDir = true
-               AtExit(func() {
-                       ctxt.Out.f.Close()
-                       os.RemoveAll(*flagTmpdir)
-               })
-       }
-
-       // change our output to temporary object file
-       ctxt.Out.f.Close()
-       mayberemoveoutfile()
-
-       p := filepath.Join(*flagTmpdir, "go.o")
-       var err error
-       f, err := os.OpenFile(p, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775)
-       if err != nil {
-               Exitf("cannot create %s: %v", p, err)
-       }
-
-       ctxt.Out.w = bufio.NewWriter(f)
-       ctxt.Out.f = f
-       ctxt.Out.off = 0
-}
-
-// hostobjCopy creates a copy of the object files in hostobj in a
-// temporary directory.
-func hostobjCopy() (paths []string) {
-       var wg sync.WaitGroup
-       sema := make(chan struct{}, runtime.NumCPU()) // limit open file descriptors
-       for i, h := range hostobj {
-               h := h
-               dst := filepath.Join(*flagTmpdir, fmt.Sprintf("%06d.o", i))
-               paths = append(paths, dst)
-
-               wg.Add(1)
-               go func() {
-                       sema <- struct{}{}
-                       defer func() {
-                               <-sema
-                               wg.Done()
-                       }()
-                       f, err := os.Open(h.file)
-                       if err != nil {
-                               Exitf("cannot reopen %s: %v", h.pn, err)
-                       }
-                       defer f.Close()
-                       if _, err := f.Seek(h.off, 0); err != nil {
-                               Exitf("cannot seek %s: %v", h.pn, err)
-                       }
-
-                       w, err := os.Create(dst)
-                       if err != nil {
-                               Exitf("cannot create %s: %v", dst, err)
-                       }
-                       if _, err := io.CopyN(w, f, h.length); err != nil {
-                               Exitf("cannot write %s: %v", dst, err)
-                       }
-                       if err := w.Close(); err != nil {
-                               Exitf("cannot close %s: %v", dst, err)
-                       }
-               }()
-       }
-       wg.Wait()
-       return paths
-}
-
-// writeGDBLinkerScript creates gcc linker script file in temp
-// directory. writeGDBLinkerScript returns created file path.
-// The script is used to work around gcc bug
-// (see https://golang.org/issue/20183 for details).
-func writeGDBLinkerScript() string {
-       name := "fix_debug_gdb_scripts.ld"
-       path := filepath.Join(*flagTmpdir, name)
-       src := `SECTIONS
-{
-  .debug_gdb_scripts BLOCK(__section_alignment__) (NOLOAD) :
-  {
-    *(.debug_gdb_scripts)
-  }
-}
-INSERT AFTER .debug_types;
-`
-       err := ioutil.WriteFile(path, []byte(src), 0666)
-       if err != nil {
-               Errorf(nil, "WriteFile %s failed: %v", name, err)
-       }
-       return path
-}
-
-// archive builds a .a archive from the hostobj object files.
-func (ctxt *Link) archive() {
-       if ctxt.BuildMode != BuildModeCArchive {
-               return
-       }
-
-       exitIfErrors()
-
-       if *flagExtar == "" {
-               *flagExtar = "ar"
-       }
-
-       mayberemoveoutfile()
-
-       // Force the buffer to flush here so that external
-       // tools will see a complete file.
-       ctxt.Out.Flush()
-       if err := ctxt.Out.f.Close(); err != nil {
-               Exitf("close: %v", err)
-       }
-       ctxt.Out.f = nil
-
-       argv := []string{*flagExtar, "-q", "-c", "-s"}
-       if ctxt.HeadType == objabi.Haix {
-               argv = append(argv, "-X64")
-       }
-       argv = append(argv, *flagOutfile)
-       argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
-       argv = append(argv, hostobjCopy()...)
-
-       if ctxt.Debugvlog != 0 {
-               ctxt.Logf("archive: %s\n", strings.Join(argv, " "))
-       }
-
-       // If supported, use syscall.Exec() to invoke the archive command,
-       // which should be the final remaining step needed for the link.
-       // This will reduce peak RSS for the link (and speed up linking of
-       // large applications), since when the archive command runs we
-       // won't be holding onto all of the linker's live memory.
-       if syscallExecSupported && !ownTmpDir {
-               runAtExitFuncs()
-               ctxt.execArchive(argv)
-               panic("should not get here")
-       }
-
-       // Otherwise invoke 'ar' in the usual way (fork + exec).
-       if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
-               Exitf("running %s failed: %v\n%s", argv[0], err, out)
-       }
-}
-
-func (ctxt *Link) hostlink() {
-       if ctxt.LinkMode != LinkExternal || nerrors > 0 {
-               return
-       }
-       if ctxt.BuildMode == BuildModeCArchive {
-               return
-       }
-
-       var argv []string
-       argv = append(argv, ctxt.extld())
-       argv = append(argv, hostlinkArchArgs(ctxt.Arch)...)
-
-       if *FlagS || debug_s {
-               if ctxt.HeadType == objabi.Hdarwin {
-                       // Recent versions of macOS print
-                       //      ld: warning: option -s is obsolete and being ignored
-                       // so do not pass any arguments.
-               } else {
-                       argv = append(argv, "-s")
-               }
-       }
-
-       switch ctxt.HeadType {
-       case objabi.Hdarwin:
-               if machoPlatform == PLATFORM_MACOS {
-                       // -headerpad is incompatible with -fembed-bitcode.
-                       argv = append(argv, "-Wl,-headerpad,1144")
-               }
-               if ctxt.DynlinkingGo() && !ctxt.Arch.InFamily(sys.ARM, sys.ARM64) {
-                       argv = append(argv, "-Wl,-flat_namespace")
-               }
-       case objabi.Hopenbsd:
-               argv = append(argv, "-Wl,-nopie")
-       case objabi.Hwindows:
-               if windowsgui {
-                       argv = append(argv, "-mwindows")
-               } else {
-                       argv = append(argv, "-mconsole")
-               }
-               // Mark as having awareness of terminal services, to avoid
-               // ancient compatibility hacks.
-               argv = append(argv, "-Wl,--tsaware")
-
-               // Enable DEP
-               argv = append(argv, "-Wl,--nxcompat")
-
-               argv = append(argv, fmt.Sprintf("-Wl,--major-os-version=%d", PeMinimumTargetMajorVersion))
-               argv = append(argv, fmt.Sprintf("-Wl,--minor-os-version=%d", PeMinimumTargetMinorVersion))
-               argv = append(argv, fmt.Sprintf("-Wl,--major-subsystem-version=%d", PeMinimumTargetMajorVersion))
-               argv = append(argv, fmt.Sprintf("-Wl,--minor-subsystem-version=%d", PeMinimumTargetMinorVersion))
-       case objabi.Haix:
-               argv = append(argv, "-pthread")
-               // prevent ld to reorder .text functions to keep the same
-               // first/last functions for moduledata.
-               argv = append(argv, "-Wl,-bnoobjreorder")
-               // mcmodel=large is needed for every gcc generated files, but
-               // ld still need -bbigtoc in order to allow larger TOC.
-               argv = append(argv, "-mcmodel=large")
-               argv = append(argv, "-Wl,-bbigtoc")
-       }
-
-       switch ctxt.BuildMode {
-       case BuildModeExe:
-               if ctxt.HeadType == objabi.Hdarwin {
-                       if machoPlatform == PLATFORM_MACOS {
-                               argv = append(argv, "-Wl,-no_pie")
-                               argv = append(argv, "-Wl,-pagezero_size,4000000")
-                       }
-               }
-       case BuildModePIE:
-               switch ctxt.HeadType {
-               case objabi.Hdarwin, objabi.Haix:
-               case objabi.Hwindows:
-                       // Enable ASLR.
-                       argv = append(argv, "-Wl,--dynamicbase")
-                       // enable high-entropy ASLR on 64-bit.
-                       if ctxt.Arch.PtrSize >= 8 {
-                               argv = append(argv, "-Wl,--high-entropy-va")
-                       }
-                       // Work around binutils limitation that strips relocation table for dynamicbase.
-                       // See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
-                       argv = append(argv, "-Wl,--export-all-symbols")
-               default:
-                       // ELF.
-                       if ctxt.UseRelro() {
-                               argv = append(argv, "-Wl,-z,relro")
-                       }
-                       argv = append(argv, "-pie")
-               }
-       case BuildModeCShared:
-               if ctxt.HeadType == objabi.Hdarwin {
-                       argv = append(argv, "-dynamiclib")
-                       if ctxt.Arch.Family != sys.AMD64 {
-                               argv = append(argv, "-Wl,-read_only_relocs,suppress")
-                       }
-               } else {
-                       // ELF.
-                       argv = append(argv, "-Wl,-Bsymbolic")
-                       if ctxt.UseRelro() {
-                               argv = append(argv, "-Wl,-z,relro")
-                       }
-                       argv = append(argv, "-shared")
-                       if ctxt.HeadType != objabi.Hwindows {
-                               // Pass -z nodelete to mark the shared library as
-                               // non-closeable: a dlclose will do nothing.
-                               argv = append(argv, "-Wl,-z,nodelete")
-                       }
-               }
-       case BuildModeShared:
-               if ctxt.UseRelro() {
-                       argv = append(argv, "-Wl,-z,relro")
-               }
-               argv = append(argv, "-shared")
-       case BuildModePlugin:
-               if ctxt.HeadType == objabi.Hdarwin {
-                       argv = append(argv, "-dynamiclib")
-               } else {
-                       if ctxt.UseRelro() {
-                               argv = append(argv, "-Wl,-z,relro")
-                       }
-                       argv = append(argv, "-shared")
-               }
-       }
-
-       if ctxt.IsELF && ctxt.DynlinkingGo() {
-               // We force all symbol resolution to be done at program startup
-               // because lazy PLT resolution can use large amounts of stack at
-               // times we cannot allow it to do so.
-               argv = append(argv, "-Wl,-znow")
-
-               // Do not let the host linker generate COPY relocations. These
-               // can move symbols out of sections that rely on stable offsets
-               // from the beginning of the section (like sym.STYPE).
-               argv = append(argv, "-Wl,-znocopyreloc")
-
-               if ctxt.Arch.InFamily(sys.ARM, sys.ARM64) && objabi.GOOS == "linux" {
-                       // On ARM, the GNU linker will generate COPY relocations
-                       // even with -znocopyreloc set.
-                       // https://sourceware.org/bugzilla/show_bug.cgi?id=19962
-                       //
-                       // On ARM64, the GNU linker will fail instead of
-                       // generating COPY relocations.
-                       //
-                       // In both cases, switch to gold.
-                       argv = append(argv, "-fuse-ld=gold")
-
-                       // If gold is not installed, gcc will silently switch
-                       // back to ld.bfd. So we parse the version information
-                       // and provide a useful error if gold is missing.
-                       cmd := exec.Command(*flagExtld, "-fuse-ld=gold", "-Wl,--version")
-                       if out, err := cmd.CombinedOutput(); err == nil {
-                               if !bytes.Contains(out, []byte("GNU gold")) {
-                                       log.Fatalf("ARM external linker must be gold (issue #15696), but is not: %s", out)
-                               }
-                       }
-               }
-       }
-
-       if ctxt.Arch.Family == sys.ARM64 && objabi.GOOS == "freebsd" {
-               // Switch to ld.bfd on freebsd/arm64.
-               argv = append(argv, "-fuse-ld=bfd")
-
-               // Provide a useful error if ld.bfd is missing.
-               cmd := exec.Command(*flagExtld, "-fuse-ld=bfd", "-Wl,--version")
-               if out, err := cmd.CombinedOutput(); err == nil {
-                       if !bytes.Contains(out, []byte("GNU ld")) {
-                               log.Fatalf("ARM64 external linker must be ld.bfd (issue #35197), please install devel/binutils")
-                       }
-               }
-       }
-
-       if ctxt.IsELF && len(buildinfo) > 0 {
-               argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo))
-       }
-
-       // On Windows, given -o foo, GCC will append ".exe" to produce
-       // "foo.exe".  We have decided that we want to honor the -o
-       // option. To make this work, we append a '.' so that GCC
-       // will decide that the file already has an extension. We
-       // only want to do this when producing a Windows output file
-       // on a Windows host.
-       outopt := *flagOutfile
-       if objabi.GOOS == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" {
-               outopt += "."
-       }
-       argv = append(argv, "-o")
-       argv = append(argv, outopt)
-
-       if rpath.val != "" {
-               argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val))
-       }
-
-       // Force global symbols to be exported for dlopen, etc.
-       if ctxt.IsELF {
-               argv = append(argv, "-rdynamic")
-       }
-       if ctxt.HeadType == objabi.Haix {
-               fileName := xcoffCreateExportFile(ctxt)
-               argv = append(argv, "-Wl,-bE:"+fileName)
-       }
-
-       if strings.Contains(argv[0], "clang") {
-               argv = append(argv, "-Qunused-arguments")
-       }
-
-       const compressDWARF = "-Wl,--compress-debug-sections=zlib-gnu"
-       if ctxt.compressDWARF && linkerFlagSupported(argv[0], compressDWARF) {
-               argv = append(argv, compressDWARF)
-       }
-
-       argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
-       argv = append(argv, hostobjCopy()...)
-       if ctxt.HeadType == objabi.Haix {
-               // We want to have C files after Go files to remove
-               // trampolines csects made by ld.
-               argv = append(argv, "-nostartfiles")
-               argv = append(argv, "/lib/crt0_64.o")
-
-               extld := ctxt.extld()
-               // Get starting files.
-               getPathFile := func(file string) string {
-                       args := []string{"-maix64", "--print-file-name=" + file}
-                       out, err := exec.Command(extld, args...).CombinedOutput()
-                       if err != nil {
-                               log.Fatalf("running %s failed: %v\n%s", extld, err, out)
-                       }
-                       return strings.Trim(string(out), "\n")
-               }
-               argv = append(argv, getPathFile("crtcxa.o"))
-               argv = append(argv, getPathFile("crtdbase.o"))
-       }
-
-       if ctxt.linkShared {
-               seenDirs := make(map[string]bool)
-               seenLibs := make(map[string]bool)
-               addshlib := func(path string) {
-                       dir, base := filepath.Split(path)
-                       if !seenDirs[dir] {
-                               argv = append(argv, "-L"+dir)
-                               if !rpath.set {
-                                       argv = append(argv, "-Wl,-rpath="+dir)
-                               }
-                               seenDirs[dir] = true
-                       }
-                       base = strings.TrimSuffix(base, ".so")
-                       base = strings.TrimPrefix(base, "lib")
-                       if !seenLibs[base] {
-                               argv = append(argv, "-l"+base)
-                               seenLibs[base] = true
-                       }
-               }
-               for _, shlib := range ctxt.Shlibs {
-                       addshlib(shlib.Path)
-                       for _, dep := range shlib.Deps {
-                               if dep == "" {
-                                       continue
-                               }
-                               libpath := findshlib(ctxt, dep)
-                               if libpath != "" {
-                                       addshlib(libpath)
-                               }
-                       }
-               }
-       }
-
-       // clang, unlike GCC, passes -rdynamic to the linker
-       // even when linking with -static, causing a linker
-       // error when using GNU ld. So take out -rdynamic if
-       // we added it. We do it in this order, rather than
-       // only adding -rdynamic later, so that -*extldflags
-       // can override -rdynamic without using -static.
-       checkStatic := func(arg string) {
-               if ctxt.IsELF && arg == "-static" {
-                       for i := range argv {
-                               if argv[i] == "-rdynamic" {
-                                       argv[i] = "-static"
-                               }
-                       }
-               }
-       }
-
-       for _, p := range ldflag {
-               argv = append(argv, p)
-               checkStatic(p)
-       }
-
-       // When building a program with the default -buildmode=exe the
-       // gc compiler generates code requires DT_TEXTREL in a
-       // position independent executable (PIE). On systems where the
-       // toolchain creates PIEs by default, and where DT_TEXTREL
-       // does not work, the resulting programs will not run. See
-       // issue #17847. To avoid this problem pass -no-pie to the
-       // toolchain if it is supported.
-       if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared {
-               // GCC uses -no-pie, clang uses -nopie.
-               for _, nopie := range []string{"-no-pie", "-nopie"} {
-                       if linkerFlagSupported(argv[0], nopie) {
-                               argv = append(argv, nopie)
-                               break
-                       }
-               }
-       }
-
-       for _, p := range strings.Fields(*flagExtldflags) {
-               argv = append(argv, p)
-               checkStatic(p)
-       }
-       if ctxt.HeadType == objabi.Hwindows {
-               // use gcc linker script to work around gcc bug
-               // (see https://golang.org/issue/20183 for details).
-               p := writeGDBLinkerScript()
-               argv = append(argv, "-Wl,-T,"+p)
-               // libmingw32 and libmingwex have some inter-dependencies,
-               // so must use linker groups.
-               argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group")
-               argv = append(argv, peimporteddlls()...)
-       }
-
-       if ctxt.Debugvlog != 0 {
-               ctxt.Logf("host link:")
-               for _, v := range argv {
-                       ctxt.Logf(" %q", v)
-               }
-               ctxt.Logf("\n")
-       }
-
-       out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput()
-       if err != nil {
-               Exitf("running %s failed: %v\n%s", argv[0], err, out)
-       }
-
-       // Filter out useless linker warnings caused by bugs outside Go.
-       // See also cmd/go/internal/work/exec.go's gccld method.
-       var save [][]byte
-       var skipLines int
-       for _, line := range bytes.SplitAfter(out, []byte("\n")) {
-               // golang.org/issue/26073 - Apple Xcode bug
-               if bytes.Contains(line, []byte("ld: warning: text-based stub file")) {
-                       continue
-               }
-
-               if skipLines > 0 {
-                       skipLines--
-                       continue
-               }
-
-               // Remove TOC overflow warning on AIX.
-               if bytes.Contains(line, []byte("ld: 0711-783")) {
-                       skipLines = 2
-                       continue
-               }
-
-               save = append(save, line)
-       }
-       out = bytes.Join(save, nil)
-
-       if len(out) > 0 {
-               // always print external output even if the command is successful, so that we don't
-               // swallow linker warnings (see https://golang.org/issue/17935).
-               ctxt.Logf("%s", out)
-       }
-
-       if !*FlagS && !*FlagW && !debug_s && ctxt.HeadType == objabi.Hdarwin {
-               dsym := filepath.Join(*flagTmpdir, "go.dwarf")
-               if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
-                       Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
-               }
-               // Skip combining if `dsymutil` didn't generate a file. See #11994.
-               if _, err := os.Stat(dsym); os.IsNotExist(err) {
-                       return
-               }
-               // For os.Rename to work reliably, must be in same directory as outfile.
-               combinedOutput := *flagOutfile + "~"
-               exef, err := os.Open(*flagOutfile)
-               if err != nil {
-                       Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
-               }
-               defer exef.Close()
-               exem, err := macho.NewFile(exef)
-               if err != nil {
-                       Exitf("%s: parsing Mach-O header failed: %v", os.Args[0], err)
-               }
-               // Only macOS supports unmapped segments such as our __DWARF segment.
-               if machoPlatform == PLATFORM_MACOS {
-                       if err := machoCombineDwarf(ctxt, exef, exem, dsym, combinedOutput); err != nil {
-                               Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
-                       }
-                       os.Remove(*flagOutfile)
-                       if err := os.Rename(combinedOutput, *flagOutfile); err != nil {
-                               Exitf("%s: %v", os.Args[0], err)
-                       }
-               }
-       }
-}
-
-var createTrivialCOnce sync.Once
-
-func linkerFlagSupported(linker, flag string) bool {
-       createTrivialCOnce.Do(func() {
-               src := filepath.Join(*flagTmpdir, "trivial.c")
-               if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil {
-                       Errorf(nil, "WriteFile trivial.c failed: %v", err)
-               }
-       })
-
-       flagsWithNextArgSkip := []string{
-               "-F",
-               "-l",
-               "-L",
-               "-framework",
-               "-Wl,-framework",
-               "-Wl,-rpath",
-               "-Wl,-undefined",
-       }
-       flagsWithNextArgKeep := []string{
-               "-arch",
-               "-isysroot",
-               "--sysroot",
-               "-target",
-       }
-       prefixesToKeep := []string{
-               "-f",
-               "-m",
-               "-p",
-               "-Wl,",
-               "-arch",
-               "-isysroot",
-               "--sysroot",
-               "-target",
-       }
-
-       var flags []string
-       keep := false
-       skip := false
-       extldflags := strings.Fields(*flagExtldflags)
-       for _, f := range append(extldflags, ldflag...) {
-               if keep {
-                       flags = append(flags, f)
-                       keep = false
-               } else if skip {
-                       skip = false
-               } else if f == "" || f[0] != '-' {
-               } else if contains(flagsWithNextArgSkip, f) {
-                       skip = true
-               } else if contains(flagsWithNextArgKeep, f) {
-                       flags = append(flags, f)
-                       keep = true
-               } else {
-                       for _, p := range prefixesToKeep {
-                               if strings.HasPrefix(f, p) {
-                                       flags = append(flags, f)
-                                       break
-                               }
-                       }
-               }
-       }
-
-       flags = append(flags, flag, "trivial.c")
-
-       cmd := exec.Command(linker, flags...)
-       cmd.Dir = *flagTmpdir
-       cmd.Env = append([]string{"LC_ALL=C"}, os.Environ()...)
-       out, err := cmd.CombinedOutput()
-       // GCC says "unrecognized command line option ‘-no-pie’"
-       // clang says "unknown argument: '-no-pie'"
-       return err == nil && !bytes.Contains(out, []byte("unrecognized")) && !bytes.Contains(out, []byte("unknown"))
-}
-
-// hostlinkArchArgs returns arguments to pass to the external linker
-// based on the architecture.
-func hostlinkArchArgs(arch *sys.Arch) []string {
-       switch arch.Family {
-       case sys.I386:
-               return []string{"-m32"}
-       case sys.AMD64, sys.S390X:
-               return []string{"-m64"}
-       case sys.ARM:
-               return []string{"-marm"}
-       case sys.ARM64:
-               // nothing needed
-       case sys.MIPS64:
-               return []string{"-mabi=64"}
-       case sys.MIPS:
-               return []string{"-mabi=32"}
-       case sys.PPC64:
-               if objabi.GOOS == "aix" {
-                       return []string{"-maix64"}
-               } else {
-                       return []string{"-m64"}
-               }
-
-       }
-       return nil
-}
-
-// ldobj loads an input object. If it is a host object (an object
-// compiled by a non-Go compiler) it returns the Hostobj pointer. If
-// it is a Go object, it returns nil.
-func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, file string) *Hostobj {
-       pkg := objabi.PathToPrefix(lib.Pkg)
-
-       eof := f.Offset() + length
-       start := f.Offset()
-       c1 := bgetc(f)
-       c2 := bgetc(f)
-       c3 := bgetc(f)
-       c4 := bgetc(f)
-       f.MustSeek(start, 0)
-
-       unit := &sym.CompilationUnit{Lib: lib}
-       lib.Units = append(lib.Units, unit)
-
-       magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
-       if magic == 0x7f454c46 { // \x7F E L F
-               if *flagNewobj {
-                       ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-                               textp, flags, err := loadelf.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn, ehdr.flags)
-                               if err != nil {
-                                       Errorf(nil, "%v", err)
-                                       return
-                               }
-                               ehdr.flags = flags
-                               ctxt.Textp = append(ctxt.Textp, textp...)
-                       }
-                       return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file)
-               } else {
-                       ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-                               textp, flags, err := loadelf.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn, ehdr.flags)
-                               if err != nil {
-                                       Errorf(nil, "%v", err)
-                                       return
-                               }
-                               ehdr.flags = flags
-                               ctxt.Textp = append(ctxt.Textp, textp...)
-                       }
-                       return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file)
-               }
-       }
-
-       if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe {
-               if *flagNewobj {
-                       ldmacho := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-                               textp, err := loadmacho.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
-                               if err != nil {
-                                       Errorf(nil, "%v", err)
-                                       return
-                               }
-                               ctxt.Textp = append(ctxt.Textp, textp...)
-                       }
-                       return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
-               } else {
-                       ldmacho := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-                               textp, err := loadmacho.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
-                               if err != nil {
-                                       Errorf(nil, "%v", err)
-                                       return
-                               }
-                               ctxt.Textp = append(ctxt.Textp, textp...)
-                       }
-                       return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
-               }
-       }
-
-       if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 {
-               if *flagNewobj {
-                       ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-                               textp, rsrc, err := loadpe.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
-                               if err != nil {
-                                       Errorf(nil, "%v", err)
-                                       return
-                               }
-                               if rsrc != nil {
-                                       setpersrc(ctxt, rsrc)
-                               }
-                               ctxt.Textp = append(ctxt.Textp, textp...)
-                       }
-                       return ldhostobj(ldpe, ctxt.HeadType, f, pkg, length, pn, file)
-               } else {
-                       ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-                               textp, rsrc, err := loadpe.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
-                               if err != nil {
-                                       Errorf(nil, "%v", err)
-                                       return
-                               }
-                               if rsrc != nil {
-                                       setpersrc(ctxt, rsrc)
-                               }
-                               ctxt.Textp = append(ctxt.Textp, textp...)
-                       }
-                       return ldhostobj(ldpe, ctxt.HeadType, f, pkg, length, pn, file)
-               }
-       }
-
-       if c1 == 0x01 && (c2 == 0xD7 || c2 == 0xF7) {
-               if *flagNewobj {
-                       ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-                               textp, err := loadxcoff.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
-                               if err != nil {
-                                       Errorf(nil, "%v", err)
-                                       return
-                               }
-                               ctxt.Textp = append(ctxt.Textp, textp...)
-                       }
-                       return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file)
-               } else {
-                       ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-                               textp, err := loadxcoff.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
-                               if err != nil {
-                                       Errorf(nil, "%v", err)
-                                       return
-                               }
-                               ctxt.Textp = append(ctxt.Textp, textp...)
-                       }
-                       return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file)
-               }
-       }
-
-       /* check the header */
-       line, err := f.ReadString('\n')
-       if err != nil {
-               Errorf(nil, "truncated object file: %s: %v", pn, err)
-               return nil
-       }
-
-       if !strings.HasPrefix(line, "go object ") {
-               if strings.HasSuffix(pn, ".go") {
-                       Exitf("%s: uncompiled .go source file", pn)
-                       return nil
-               }
-
-               if line == ctxt.Arch.Name {
-                       // old header format: just $GOOS
-                       Errorf(nil, "%s: stale object file", pn)
-                       return nil
-               }
-
-               Errorf(nil, "%s: not an object file", pn)
-               return nil
-       }
-
-       // First, check that the basic GOOS, GOARCH, and Version match.
-       t := fmt.Sprintf("%s %s %s ", objabi.GOOS, objabi.GOARCH, objabi.Version)
-
-       line = strings.TrimRight(line, "\n")
-       if !strings.HasPrefix(line[10:]+" ", t) && !*flagF {
-               Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], t)
-               return nil
-       }
-
-       // Second, check that longer lines match each other exactly,
-       // so that the Go compiler and write additional information
-       // that must be the same from run to run.
-       if len(line) >= len(t)+10 {
-               if theline == "" {
-                       theline = line[10:]
-               } else if theline != line[10:] {
-                       Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], theline)
-                       return nil
-               }
-       }
-
-       // Skip over exports and other info -- ends with \n!\n.
-       //
-       // Note: It's possible for "\n!\n" to appear within the binary
-       // package export data format. To avoid truncating the package
-       // definition prematurely (issue 21703), we keep track of
-       // how many "$$" delimiters we've seen.
-
-       import0 := f.Offset()
-
-       c1 = '\n' // the last line ended in \n
-       c2 = bgetc(f)
-       c3 = bgetc(f)
-       markers := 0
-       for {
-               if c1 == '\n' {
-                       if markers%2 == 0 && c2 == '!' && c3 == '\n' {
-                               break
-                       }
-                       if c2 == '$' && c3 == '$' {
-                               markers++
-                       }
-               }
-
-               c1 = c2
-               c2 = c3
-               c3 = bgetc(f)
-               if c3 == -1 {
-                       Errorf(nil, "truncated object file: %s", pn)
-                       return nil
-               }
-       }
-
-       import1 := f.Offset()
-
-       f.MustSeek(import0, 0)
-       ldpkg(ctxt, f, lib, import1-import0-2, pn) // -2 for !\n
-       f.MustSeek(import1, 0)
-
-       flags := 0
-       switch *FlagStrictDups {
-       case 0:
-               break
-       case 1:
-               flags = objfile.StrictDupsWarnFlag
-       case 2:
-               flags = objfile.StrictDupsErrFlag
-       default:
-               log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups)
-       }
-       var c int
-       if *flagNewobj {
-               ctxt.loader.Preload(ctxt.Arch, ctxt.Syms, f, lib, unit, eof-f.Offset(), pn, flags)
-       } else {
-               c = objfile.Load(ctxt.Arch, ctxt.Syms, f, lib, unit, eof-f.Offset(), pn, flags)
-       }
-       strictDupMsgCount += c
-       addImports(ctxt, lib, pn)
-       return nil
-}
-
-func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte {
-       data := make([]byte, sym.Size)
-       sect := f.Sections[sym.Section]
-       if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE {
-               Errorf(nil, "reading %s from non-data section", sym.Name)
-       }
-       n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr))
-       if uint64(n) != sym.Size {
-               Errorf(nil, "reading contents of %s: %v", sym.Name, err)
-       }
-       return data
-}
-
-func readwithpad(r io.Reader, sz int32) ([]byte, error) {
-       data := make([]byte, Rnd(int64(sz), 4))
-       _, err := io.ReadFull(r, data)
-       if err != nil {
-               return nil, err
-       }
-       data = data[:sz]
-       return data, nil
-}
-
-func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) {
-       for _, sect := range f.Sections {
-               if sect.Type != elf.SHT_NOTE {
-                       continue
-               }
-               r := sect.Open()
-               for {
-                       var namesize, descsize, noteType int32
-                       err := binary.Read(r, f.ByteOrder, &namesize)
-                       if err != nil {
-                               if err == io.EOF {
-                                       break
-                               }
-                               return nil, fmt.Errorf("read namesize failed: %v", err)
-                       }
-                       err = binary.Read(r, f.ByteOrder, &descsize)
-                       if err != nil {
-                               return nil, fmt.Errorf("read descsize failed: %v", err)
-                       }
-                       err = binary.Read(r, f.ByteOrder, &noteType)
-                       if err != nil {
-                               return nil, fmt.Errorf("read type failed: %v", err)
-                       }
-                       noteName, err := readwithpad(r, namesize)
-                       if err != nil {
-                               return nil, fmt.Errorf("read name failed: %v", err)
-                       }
-                       desc, err := readwithpad(r, descsize)
-                       if err != nil {
-                               return nil, fmt.Errorf("read desc failed: %v", err)
-                       }
-                       if string(name) == string(noteName) && typ == noteType {
-                               return desc, nil
-                       }
-               }
-       }
-       return nil, nil
-}
-
-func findshlib(ctxt *Link, shlib string) string {
-       if filepath.IsAbs(shlib) {
-               return shlib
-       }
-       for _, libdir := range ctxt.Libdir {
-               libpath := filepath.Join(libdir, shlib)
-               if _, err := os.Stat(libpath); err == nil {
-                       return libpath
-               }
-       }
-       Errorf(nil, "cannot find shared library: %s", shlib)
-       return ""
-}
-
-func ldshlibsyms(ctxt *Link, shlib string) {
-       var libpath string
-       if filepath.IsAbs(shlib) {
-               libpath = shlib
-               shlib = filepath.Base(shlib)
-       } else {
-               libpath = findshlib(ctxt, shlib)
-               if libpath == "" {
-                       return
-               }
-       }
-       for _, processedlib := range ctxt.Shlibs {
-               if processedlib.Path == libpath {
-                       return
-               }
-       }
-       if ctxt.Debugvlog > 1 {
-               ctxt.Logf("ldshlibsyms: found library with name %s at %s\n", shlib, libpath)
-       }
-
-       f, err := elf.Open(libpath)
-       if err != nil {
-               Errorf(nil, "cannot open shared library: %s", libpath)
-               return
-       }
-       defer f.Close()
-
-       hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG)
-       if err != nil {
-               Errorf(nil, "cannot read ABI hash from shared library %s: %v", libpath, err)
-               return
-       }
-
-       depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG)
-       if err != nil {
-               Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err)
-               return
-       }
-       var deps []string
-       for _, dep := range strings.Split(string(depsbytes), "\n") {
-               if dep == "" {
-                       continue
-               }
-               if !filepath.IsAbs(dep) {
-                       // If the dep can be interpreted as a path relative to the shlib
-                       // in which it was found, do that. Otherwise, we will leave it
-                       // to be resolved by libdir lookup.
-                       abs := filepath.Join(filepath.Dir(libpath), dep)
-                       if _, err := os.Stat(abs); err == nil {
-                               dep = abs
-                       }
-               }
-               deps = append(deps, dep)
-       }
-
-       syms, err := f.DynamicSymbols()
-       if err != nil {
-               Errorf(nil, "cannot read symbols from shared library: %s", libpath)
-               return
-       }
-       gcdataLocations := make(map[uint64]*sym.Symbol)
-       for _, elfsym := range syms {
-               if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
-                       continue
-               }
-
-               // Symbols whose names start with "type." are compiler
-               // generated, so make functions with that prefix internal.
-               ver := 0
-               if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type.") {
-                       ver = sym.SymVerABIInternal
-               }
-
-               var lsym *sym.Symbol
-               if *flagNewobj {
-                       i := ctxt.loader.AddExtSym(elfsym.Name, ver)
-                       if i == 0 {
-                               continue
-                       }
-                       lsym = ctxt.Syms.Newsym(elfsym.Name, ver)
-                       ctxt.loader.Syms[i] = lsym
-               } else {
-                       lsym = ctxt.Syms.Lookup(elfsym.Name, ver)
-               }
-               // Because loadlib above loads all .a files before loading any shared
-               // libraries, any non-dynimport symbols we find that duplicate symbols
-               // already loaded should be ignored (the symbols from the .a files
-               // "win").
-               if lsym.Type != 0 && lsym.Type != sym.SDYNIMPORT {
-                       continue
-               }
-               lsym.Type = sym.SDYNIMPORT
-               lsym.SetElfType(elf.ST_TYPE(elfsym.Info))
-               lsym.Size = int64(elfsym.Size)
-               if elfsym.Section != elf.SHN_UNDEF {
-                       // Set .File for the library that actually defines the symbol.
-                       lsym.File = libpath
-                       // The decodetype_* functions in decodetype.go need access to
-                       // the type data.
-                       if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") {
-                               lsym.P = readelfsymboldata(ctxt, f, &elfsym)
-                               gcdataLocations[elfsym.Value+2*uint64(ctxt.Arch.PtrSize)+8+1*uint64(ctxt.Arch.PtrSize)] = lsym
-                       }
-               }
-               // For function symbols, we don't know what ABI is
-               // available, so alias it under both ABIs.
-               //
-               // TODO(austin): This is almost certainly wrong once
-               // the ABIs are actually different. We might have to
-               // mangle Go function names in the .so to include the
-               // ABI.
-               if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && ver == 0 {
-                       var alias *sym.Symbol
-                       if *flagNewobj {
-                               i := ctxt.loader.AddExtSym(elfsym.Name, sym.SymVerABIInternal)
-                               if i == 0 {
-                                       continue
-                               }
-                               alias = ctxt.Syms.Newsym(elfsym.Name, sym.SymVerABIInternal)
-                               ctxt.loader.Syms[i] = alias
-                       } else {
-                               alias = ctxt.Syms.Lookup(elfsym.Name, sym.SymVerABIInternal)
-                       }
-                       if alias.Type != 0 {
-                               continue
-                       }
-                       alias.Type = sym.SABIALIAS
-                       alias.R = []sym.Reloc{{Sym: lsym}}
-               }
-       }
-       gcdataAddresses := make(map[*sym.Symbol]uint64)
-       if ctxt.Arch.Family == sys.ARM64 {
-               for _, sect := range f.Sections {
-                       if sect.Type == elf.SHT_RELA {
-                               var rela elf.Rela64
-                               rdr := sect.Open()
-                               for {
-                                       err := binary.Read(rdr, f.ByteOrder, &rela)
-                                       if err == io.EOF {
-                                               break
-                                       } else if err != nil {
-                                               Errorf(nil, "reading relocation failed %v", err)
-                                               return
-                                       }
-                                       t := elf.R_AARCH64(rela.Info & 0xffff)
-                                       if t != elf.R_AARCH64_RELATIVE {
-                                               continue
-                                       }
-                                       if lsym, ok := gcdataLocations[rela.Off]; ok {
-                                               gcdataAddresses[lsym] = uint64(rela.Addend)
-                                       }
-                               }
-                       }
-               }
-       }
-
-       ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdataAddresses: gcdataAddresses})
-}
-
-func addsection(arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section {
-       sect := new(sym.Section)
-       sect.Rwx = uint8(rwx)
-       sect.Name = name
-       sect.Seg = seg
-       sect.Align = int32(arch.PtrSize) // everything is at least pointer-aligned
-       seg.Sections = append(seg.Sections, sect)
-       return sect
-}
-
-type chain struct {
-       sym   *sym.Symbol
-       up    *chain
-       limit int // limit on entry to sym
-}
-
-var morestack *sym.Symbol
-
-// TODO: Record enough information in new object files to
-// allow stack checks here.
-
-func haslinkregister(ctxt *Link) bool {
-       return ctxt.FixedFrameSize() != 0
-}
-
-func callsize(ctxt *Link) int {
-       if haslinkregister(ctxt) {
-               return 0
-       }
-       return ctxt.Arch.RegSize
-}
-
-func (ctxt *Link) dostkcheck() {
-       var ch chain
-
-       morestack = ctxt.Syms.Lookup("runtime.morestack", 0)
-
-       // Every splitting function ensures that there are at least StackLimit
-       // bytes available below SP when the splitting prologue finishes.
-       // If the splitting function calls F, then F begins execution with
-       // at least StackLimit - callsize() bytes available.
-       // Check that every function behaves correctly with this amount
-       // of stack, following direct calls in order to piece together chains
-       // of non-splitting functions.
-       ch.up = nil
-
-       ch.limit = objabi.StackLimit - callsize(ctxt)
-       if objabi.GOARCH == "arm64" {
-               // need extra 8 bytes below SP to save FP
-               ch.limit -= 8
-       }
-
-       // Check every function, but do the nosplit functions in a first pass,
-       // to make the printed failure chains as short as possible.
-       for _, s := range ctxt.Textp {
-               // runtime.racesymbolizethunk is called from gcc-compiled C
-               // code running on the operating system thread stack.
-               // It uses more than the usual amount of stack but that's okay.
-               if s.Name == "runtime.racesymbolizethunk" {
-                       continue
-               }
-
-               if s.Attr.NoSplit() {
-                       ch.sym = s
-                       stkcheck(ctxt, &ch, 0)
-               }
-       }
-
-       for _, s := range ctxt.Textp {
-               if !s.Attr.NoSplit() {
-                       ch.sym = s
-                       stkcheck(ctxt, &ch, 0)
-               }
-       }
-}
-
-func stkcheck(ctxt *Link, up *chain, depth int) int {
-       limit := up.limit
-       s := up.sym
-
-       // Don't duplicate work: only need to consider each
-       // function at top of safe zone once.
-       top := limit == objabi.StackLimit-callsize(ctxt)
-       if top {
-               if s.Attr.StackCheck() {
-                       return 0
-               }
-               s.Attr |= sym.AttrStackCheck
-       }
-
-       if depth > 500 {
-               Errorf(s, "nosplit stack check too deep")
-               stkbroke(ctxt, up, 0)
-               return -1
-       }
-
-       if s.Attr.External() || s.FuncInfo == nil {
-               // external function.
-               // should never be called directly.
-               // onlyctxt.Diagnose the direct caller.
-               // TODO(mwhudson): actually think about this.
-               // TODO(khr): disabled for now. Calls to external functions can only happen on the g0 stack.
-               // See the trampolines in src/runtime/sys_darwin_$ARCH.go.
-               if depth == 1 && s.Type != sym.SXREF && !ctxt.DynlinkingGo() &&
-                       ctxt.BuildMode != BuildModeCArchive && ctxt.BuildMode != BuildModePIE && ctxt.BuildMode != BuildModeCShared && ctxt.BuildMode != BuildModePlugin {
-                       //Errorf(s, "call to external function")
-               }
-               return -1
-       }
-
-       if limit < 0 {
-               stkbroke(ctxt, up, limit)
-               return -1
-       }
-
-       // morestack looks like it calls functions,
-       // but it switches the stack pointer first.
-       if s == morestack {
-               return 0
-       }
-
-       var ch chain
-       ch.up = up
-
-       if !s.Attr.NoSplit() {
-               // Ensure we have enough stack to call morestack.
-               ch.limit = limit - callsize(ctxt)
-               ch.sym = morestack
-               if stkcheck(ctxt, &ch, depth+1) < 0 {
-                       return -1
-               }
-               if !top {
-                       return 0
-               }
-               // Raise limit to allow frame.
-               locals := int32(0)
-               if s.FuncInfo != nil {
-                       locals = s.FuncInfo.Locals
-               }
-               limit = objabi.StackLimit + int(locals) + int(ctxt.FixedFrameSize())
-       }
-
-       // Walk through sp adjustments in function, consuming relocs.
-       ri := 0
-
-       endr := len(s.R)
-       var ch1 chain
-       pcsp := obj.NewPCIter(uint32(ctxt.Arch.MinLC))
-       var r *sym.Reloc
-       for pcsp.Init(s.FuncInfo.Pcsp.P); !pcsp.Done; pcsp.Next() {
-               // pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
-
-               // Check stack size in effect for this span.
-               if int32(limit)-pcsp.Value < 0 {
-                       stkbroke(ctxt, up, int(int32(limit)-pcsp.Value))
-                       return -1
-               }
-
-               // Process calls in this span.
-               for ; ri < endr && uint32(s.R[ri].Off) < pcsp.NextPC; ri++ {
-                       r = &s.R[ri]
-                       switch {
-                       case r.Type.IsDirectCall():
-                               ch.limit = int(int32(limit) - pcsp.Value - int32(callsize(ctxt)))
-                               ch.sym = r.Sym
-                               if stkcheck(ctxt, &ch, depth+1) < 0 {
-                                       return -1
-                               }
-
-                       // Indirect call. Assume it is a call to a splitting function,
-                       // so we have to make sure it can call morestack.
-                       // Arrange the data structures to report both calls, so that
-                       // if there is an error, stkprint shows all the steps involved.
-                       case r.Type == objabi.R_CALLIND:
-                               ch.limit = int(int32(limit) - pcsp.Value - int32(callsize(ctxt)))
-                               ch.sym = nil
-                               ch1.limit = ch.limit - callsize(ctxt) // for morestack in called prologue
-                               ch1.up = &ch
-                               ch1.sym = morestack
-                               if stkcheck(ctxt, &ch1, depth+2) < 0 {
-                                       return -1
-                               }
-                       }
-               }
-       }
-
-       return 0
-}
-
-func stkbroke(ctxt *Link, ch *chain, limit int) {
-       Errorf(ch.sym, "nosplit stack overflow")
-       stkprint(ctxt, ch, limit)
-}
-
-func stkprint(ctxt *Link, ch *chain, limit int) {
-       var name string
-
-       if ch.sym != nil {
-               name = ch.sym.Name
-               if ch.sym.Attr.NoSplit() {
-                       name += " (nosplit)"
-               }
-       } else {
-               name = "function pointer"
-       }
-
-       if ch.up == nil {
-               // top of chain.  ch->sym != nil.
-               if ch.sym.Attr.NoSplit() {
-                       fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name)
-               } else {
-                       fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name)
-               }
-       } else {
-               stkprint(ctxt, ch.up, ch.limit+callsize(ctxt))
-               if !haslinkregister(ctxt) {
-                       fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name)
-               }
-       }
-
-       if ch.limit != limit {
-               fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit)
-       }
-}
-
-func usage() {
-       fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n")
-       objabi.Flagprint(os.Stderr)
-       Exit(2)
-}
-
-type SymbolType int8
-
-const (
-       // see also https://9p.io/magic/man2html/1/nm
-       TextSym      SymbolType = 'T'
-       DataSym      SymbolType = 'D'
-       BSSSym       SymbolType = 'B'
-       UndefinedSym SymbolType = 'U'
-       TLSSym       SymbolType = 't'
-       FrameSym     SymbolType = 'm'
-       ParamSym     SymbolType = 'p'
-       AutoSym      SymbolType = 'a'
-
-       // Deleted auto (not a real sym, just placeholder for type)
-       DeletedAutoSym = 'x'
-)
-
-func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int64, *sym.Symbol)) {
-       // These symbols won't show up in the first loop below because we
-       // skip sym.STEXT symbols. Normal sym.STEXT symbols are emitted by walking textp.
-       s := ctxt.Syms.Lookup("runtime.text", 0)
-       if s.Type == sym.STEXT {
-               // We've already included this symbol in ctxt.Textp
-               // if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin or
-               // on AIX with external linker.
-               // See data.go:/textaddress
-               if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
-                       put(ctxt, s, s.Name, TextSym, s.Value, nil)
-               }
-       }
-
-       n := 0
-
-       // Generate base addresses for all text sections if there are multiple
-       for _, sect := range Segtext.Sections {
-               if n == 0 {
-                       n++
-                       continue
-               }
-               if sect.Name != ".text" || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
-                       // On AIX, runtime.text.X are symbols already in the symtab.
-                       break
-               }
-               s = ctxt.Syms.ROLookup(fmt.Sprintf("runtime.text.%d", n), 0)
-               if s == nil {
-                       break
-               }
-               if s.Type == sym.STEXT {
-                       put(ctxt, s, s.Name, TextSym, s.Value, nil)
-               }
-               n++
-       }
-
-       s = ctxt.Syms.Lookup("runtime.etext", 0)
-       if s.Type == sym.STEXT {
-               // We've already included this symbol in ctxt.Textp
-               // if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin or
-               // on AIX with external linker.
-               // See data.go:/textaddress
-               if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
-                       put(ctxt, s, s.Name, TextSym, s.Value, nil)
-               }
-       }
-
-       shouldBeInSymbolTable := func(s *sym.Symbol) bool {
-               if s.Attr.NotInSymbolTable() {
-                       return false
-               }
-               if ctxt.HeadType == objabi.Haix && s.Name == ".go.buildinfo" {
-                       // On AIX, .go.buildinfo must be in the symbol table as
-                       // it has relocations.
-                       return true
-               }
-               if (s.Name == "" || s.Name[0] == '.') && !s.IsFileLocal() && s.Name != ".rathole" && s.Name != ".TOC." {
-                       return false
-               }
-               return true
-       }
-
-       for _, s := range ctxt.Syms.Allsym {
-               if !shouldBeInSymbolTable(s) {
-                       continue
-               }
-               switch s.Type {
-               case sym.SCONST,
-                       sym.SRODATA,
-                       sym.SSYMTAB,
-                       sym.SPCLNTAB,
-                       sym.SINITARR,
-                       sym.SDATA,
-                       sym.SNOPTRDATA,
-                       sym.SELFROSECT,
-                       sym.SMACHOGOT,
-                       sym.STYPE,
-                       sym.SSTRING,
-                       sym.SGOSTRING,
-                       sym.SGOFUNC,
-                       sym.SGCBITS,
-                       sym.STYPERELRO,
-                       sym.SSTRINGRELRO,
-                       sym.SGOSTRINGRELRO,
-                       sym.SGOFUNCRELRO,
-                       sym.SGCBITSRELRO,
-                       sym.SRODATARELRO,
-                       sym.STYPELINK,
-                       sym.SITABLINK,
-                       sym.SWINDOWS:
-                       if !s.Attr.Reachable() {
-                               continue
-                       }
-                       put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype)
-
-               case sym.SBSS, sym.SNOPTRBSS, sym.SLIBFUZZER_EXTRA_COUNTER:
-                       if !s.Attr.Reachable() {
-                               continue
-                       }
-                       if len(s.P) > 0 {
-                               Errorf(s, "should not be bss (size=%d type=%v special=%v)", len(s.P), s.Type, s.Attr.Special())
-                       }
-                       put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype)
-
-               case sym.SUNDEFEXT:
-                       if ctxt.HeadType == objabi.Hwindows || ctxt.HeadType == objabi.Haix || ctxt.IsELF {
-                               put(ctxt, s, s.Name, UndefinedSym, s.Value, nil)
-                       }
-
-               case sym.SHOSTOBJ:
-                       if !s.Attr.Reachable() {
-                               continue
-                       }
-                       if ctxt.HeadType == objabi.Hwindows || ctxt.IsELF {
-                               put(ctxt, s, s.Name, UndefinedSym, s.Value, nil)
-                       }
-
-               case sym.SDYNIMPORT:
-                       if !s.Attr.Reachable() {
-                               continue
-                       }
-                       put(ctxt, s, s.Extname(), UndefinedSym, 0, nil)
-
-               case sym.STLSBSS:
-                       if ctxt.LinkMode == LinkExternal {
-                               put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype)
-                       }
-               }
-       }
-
-       for _, s := range ctxt.Textp {
-               put(ctxt, s, s.Name, TextSym, s.Value, s.Gotype)
-
-               locals := int32(0)
-               if s.FuncInfo != nil {
-                       locals = s.FuncInfo.Locals
-               }
-               // NOTE(ality): acid can't produce a stack trace without .frame symbols
-               put(ctxt, nil, ".frame", FrameSym, int64(locals)+int64(ctxt.Arch.PtrSize), nil)
-
-               if s.FuncInfo == nil {
-                       continue
-               }
-       }
-
-       if ctxt.Debugvlog != 0 || *flagN {
-               ctxt.Logf("symsize = %d\n", uint32(Symsize))
-       }
-}
-
-func Symaddr(s *sym.Symbol) int64 {
-       if !s.Attr.Reachable() {
-               Errorf(s, "unreachable symbol in symaddr")
-       }
-       return s.Value
-}
-
-func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) {
-       s := ctxt.Syms.Lookup(p, 0)
-       s.Type = t
-       s.Value = v
-       s.Attr |= sym.AttrReachable
-       s.Attr |= sym.AttrSpecial
-       s.Attr |= sym.AttrLocal
-}
-
-func datoff(s *sym.Symbol, addr int64) int64 {
-       if uint64(addr) >= Segdata.Vaddr {
-               return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
-       }
-       if uint64(addr) >= Segtext.Vaddr {
-               return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff)
-       }
-       Errorf(s, "invalid datoff %#x", addr)
-       return 0
-}
-
-func Entryvalue(ctxt *Link) int64 {
-       a := *flagEntrySymbol
-       if a[0] >= '0' && a[0] <= '9' {
-               return atolwhex(a)
-       }
-       s := ctxt.Syms.Lookup(a, 0)
-       if s.Type == 0 {
-               return *FlagTextAddr
-       }
-       if ctxt.HeadType != objabi.Haix && s.Type != sym.STEXT {
-               Errorf(s, "entry not text")
-       }
-       return s.Value
-}
-
-func undefsym(ctxt *Link, s *sym.Symbol) {
-       var r *sym.Reloc
-
-       for i := 0; i < len(s.R); i++ {
-               r = &s.R[i]
-               if r.Sym == nil { // happens for some external ARM relocs
-                       continue
-               }
-               // TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
-               // sense and should be removed when someone has thought about it properly.
-               if (r.Sym.Type == sym.Sxxx || r.Sym.Type == sym.SXREF) && !r.Sym.Attr.VisibilityHidden() {
-                       Errorf(s, "undefined: %q", r.Sym.Name)
-               }
-               if !r.Sym.Attr.Reachable() && r.Type != objabi.R_WEAKADDROFF {
-                       Errorf(s, "relocation target %q", r.Sym.Name)
-               }
-       }
-}
-
-func (ctxt *Link) undef() {
-       // undefsym performs checks (almost) identical to checks
-       // that report undefined relocations in relocsym.
-       // Both undefsym and relocsym can report same symbol as undefined,
-       // which results in error message duplication (see #10978).
-       //
-       // The undef is run after Arch.Asmb and could detect some
-       // programming errors there, but if object being linked is already
-       // failed with errors, it is better to avoid duplicated errors.
-       if nerrors > 0 {
-               return
-       }
-
-       for _, s := range ctxt.Textp {
-               undefsym(ctxt, s)
-       }
-       for _, s := range datap {
-               undefsym(ctxt, s)
-       }
-       if nerrors > 0 {
-               errorexit()
-       }
-}
-
-func (ctxt *Link) callgraph() {
-       if !*FlagC {
-               return
-       }
-
-       var i int
-       var r *sym.Reloc
-       for _, s := range ctxt.Textp {
-               for i = 0; i < len(s.R); i++ {
-                       r = &s.R[i]
-                       if r.Sym == nil {
-                               continue
-                       }
-                       if r.Type.IsDirectCall() && r.Sym.Type == sym.STEXT {
-                               ctxt.Logf("%s calls %s\n", s.Name, r.Sym.Name)
-                       }
-               }
-       }
-}
-
-func Rnd(v int64, r int64) int64 {
-       if r <= 0 {
-               return v
-       }
-       v += r - 1
-       c := v % r
-       if c < 0 {
-               c += r
-       }
-       v -= c
-       return v
-}
-
-func bgetc(r *bio.Reader) int {
-       c, err := r.ReadByte()
-       if err != nil {
-               if err != io.EOF {
-                       log.Fatalf("reading input: %v", err)
-               }
-               return -1
-       }
-       return int(c)
-}
-
-type markKind uint8 // for postorder traversal
-const (
-       _ markKind = iota
-       visiting
-       visited
-)
-
-func postorder(libs []*sym.Library) []*sym.Library {
-       order := make([]*sym.Library, 0, len(libs)) // hold the result
-       mark := make(map[*sym.Library]markKind, len(libs))
-       for _, lib := range libs {
-               dfs(lib, mark, &order)
-       }
-       return order
-}
-
-func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library) {
-       if mark[lib] == visited {
-               return
-       }
-       if mark[lib] == visiting {
-               panic("found import cycle while visiting " + lib.Pkg)
-       }
-       mark[lib] = visiting
-       for _, i := range lib.Imports {
-               dfs(i, mark, order)
-       }
-       mark[lib] = visited
-       *order = append(*order, lib)
-}
-
-func (ctxt *Link) loadlibfull() {
-       // Load full symbol contents, resolve indexed references.
-       ctxt.loader.LoadFull(ctxt.Arch, ctxt.Syms)
-
-       // Pull the symbols out.
-       ctxt.loader.ExtractSymbols(ctxt.Syms)
-
-       // Load cgo directives.
-       for _, d := range ctxt.cgodata {
-               setCgoAttr(ctxt, ctxt.Syms.Lookup, d.file, d.pkg, d.directives)
-       }
-
-       setupdynexp(ctxt)
-
-       // Populate ctxt.Reachparent if appropriate.
-       if ctxt.Reachparent != nil {
-               for i := 0; i < len(ctxt.loader.Reachparent); i++ {
-                       p := ctxt.loader.Reachparent[i]
-                       if p == 0 {
-                               continue
-                       }
-                       if p == loader.Sym(i) {
-                               panic("self-cycle in reachparent")
-                       }
-                       sym := ctxt.loader.Syms[i]
-                       psym := ctxt.loader.Syms[p]
-                       ctxt.Reachparent[sym] = psym
-               }
-       }
-
-       // Drop the reference.
-       ctxt.loader = nil
-       ctxt.cgodata = nil
-
-       addToTextp(ctxt)
-}
-
-func (ctxt *Link) dumpsyms() {
-       for _, s := range ctxt.Syms.Allsym {
-               fmt.Printf("%s %s %p %v %v\n", s, s.Type, s, s.Attr.Reachable(), s.Attr.OnList())
-               for i := range s.R {
-                       fmt.Println("\t", s.R[i].Type, s.R[i].Sym)
-               }
-       }
-}
diff --git a/src/cmd/oldlink/internal/ld/link.go b/src/cmd/oldlink/internal/ld/link.go
deleted file mode 100644 (file)
index 15878f3..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-// Derived from Inferno utils/6l/l.h and related files.
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ld
-
-import (
-       "bufio"
-       "cmd/internal/obj"
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/loader"
-       "cmd/oldlink/internal/sym"
-       "debug/elf"
-       "fmt"
-)
-
-type Shlib struct {
-       Path            string
-       Hash            []byte
-       Deps            []string
-       File            *elf.File
-       gcdataAddresses map[*sym.Symbol]uint64
-}
-
-// Link holds the context for writing object code from a compiler
-// or for reading that input into the linker.
-type Link struct {
-       Out *OutBuf
-
-       Syms *sym.Symbols
-
-       Arch      *sys.Arch
-       Debugvlog int
-       Bso       *bufio.Writer
-
-       Loaded bool // set after all inputs have been loaded as symbols
-
-       IsELF    bool
-       HeadType objabi.HeadType
-
-       linkShared    bool // link against installed Go shared libraries
-       LinkMode      LinkMode
-       BuildMode     BuildMode
-       canUsePlugins bool // initialized when Loaded is set to true
-       compressDWARF bool
-
-       Tlsg         *sym.Symbol
-       Libdir       []string
-       Library      []*sym.Library
-       LibraryByPkg map[string]*sym.Library
-       Shlibs       []Shlib
-       Tlsoffset    int
-       Textp        []*sym.Symbol
-       Filesyms     []*sym.Symbol
-       Moduledata   *sym.Symbol
-
-       PackageFile  map[string]string
-       PackageShlib map[string]string
-
-       tramps []*sym.Symbol // trampolines
-
-       // unresolvedSymSet is a set of erroneous unresolved references.
-       // Used to avoid duplicated error messages.
-       unresolvedSymSet map[unresolvedSymKey]bool
-
-       // Used to implement field tracking.
-       Reachparent map[*sym.Symbol]*sym.Symbol
-
-       compUnits []*sym.CompilationUnit // DWARF compilation units
-       runtimeCU *sym.CompilationUnit   // One of the runtime CUs, the last one seen.
-
-       relocbuf []byte // temporary buffer for applying relocations
-
-       loader  *loader.Loader
-       cgodata []cgodata // cgo directives to load, three strings are args for loadcgo
-
-       cgo_export_static  map[string]bool
-       cgo_export_dynamic map[string]bool
-}
-
-type cgodata struct {
-       file       string
-       pkg        string
-       directives [][]string
-}
-
-type unresolvedSymKey struct {
-       from *sym.Symbol // Symbol that referenced unresolved "to"
-       to   *sym.Symbol // Unresolved symbol referenced by "from"
-}
-
-// ErrorUnresolved prints unresolved symbol error for r.Sym that is referenced from s.
-func (ctxt *Link) ErrorUnresolved(s *sym.Symbol, r *sym.Reloc) {
-       if ctxt.unresolvedSymSet == nil {
-               ctxt.unresolvedSymSet = make(map[unresolvedSymKey]bool)
-       }
-
-       k := unresolvedSymKey{from: s, to: r.Sym}
-       if !ctxt.unresolvedSymSet[k] {
-               ctxt.unresolvedSymSet[k] = true
-
-               // Try to find symbol under another ABI.
-               var reqABI, haveABI obj.ABI
-               haveABI = ^obj.ABI(0)
-               reqABI, ok := sym.VersionToABI(int(r.Sym.Version))
-               if ok {
-                       for abi := obj.ABI(0); abi < obj.ABICount; abi++ {
-                               v := sym.ABIToVersion(abi)
-                               if v == -1 {
-                                       continue
-                               }
-                               if rs := ctxt.Syms.ROLookup(r.Sym.Name, v); rs != nil && rs.Type != sym.Sxxx && rs.Type != sym.SXREF {
-                                       haveABI = abi
-                               }
-                       }
-               }
-
-               // Give a special error message for main symbol (see #24809).
-               if r.Sym.Name == "main.main" {
-                       Errorf(s, "function main is undeclared in the main package")
-               } else if haveABI != ^obj.ABI(0) {
-                       Errorf(s, "relocation target %s not defined for %s (but is defined for %s)", r.Sym.Name, reqABI, haveABI)
-               } else {
-                       Errorf(s, "relocation target %s not defined", r.Sym.Name)
-               }
-       }
-}
-
-// The smallest possible offset from the hardware stack pointer to a local
-// variable on the stack. Architectures that use a link register save its value
-// on the stack in the function prologue and so always have a pointer between
-// the hardware stack pointer and the local variable area.
-func (ctxt *Link) FixedFrameSize() int64 {
-       switch ctxt.Arch.Family {
-       case sys.AMD64, sys.I386:
-               return 0
-       case sys.PPC64:
-               // PIC code on ppc64le requires 32 bytes of stack, and it's easier to
-               // just use that much stack always on ppc64x.
-               return int64(4 * ctxt.Arch.PtrSize)
-       default:
-               return int64(ctxt.Arch.PtrSize)
-       }
-}
-
-func (ctxt *Link) Logf(format string, args ...interface{}) {
-       fmt.Fprintf(ctxt.Bso, format, args...)
-       ctxt.Bso.Flush()
-}
-
-func addImports(ctxt *Link, l *sym.Library, pn string) {
-       pkg := objabi.PathToPrefix(l.Pkg)
-       for _, importStr := range l.ImportStrings {
-               lib := addlib(ctxt, pkg, pn, importStr)
-               if lib != nil {
-                       l.Imports = append(l.Imports, lib)
-               }
-       }
-       l.ImportStrings = nil
-}
diff --git a/src/cmd/oldlink/internal/ld/macho.go b/src/cmd/oldlink/internal/ld/macho.go
deleted file mode 100644 (file)
index 960ed29..0000000
+++ /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 (file)
index 9d9f916..0000000
+++ /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 (file)
index f7f3700..0000000
+++ /dev/null
@@ -1,338 +0,0 @@
-// Inferno utils/6l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ld
-
-import (
-       "bufio"
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/sym"
-       "flag"
-       "log"
-       "os"
-       "runtime"
-       "runtime/pprof"
-       "strings"
-)
-
-var (
-       pkglistfornote []byte
-       windowsgui     bool // writes a "GUI binary" instead of a "console binary"
-       ownTmpDir      bool // set to true if tmp dir created by linker (e.g. no -tmpdir)
-)
-
-func init() {
-       flag.Var(&rpath, "r", "set the ELF dynamic linker search `path` to dir1:dir2:...")
-}
-
-// Flags used by the linker. The exported flags are used by the architecture-specific packages.
-var (
-       flagBuildid = flag.String("buildid", "", "record `id` as Go toolchain build id")
-
-       flagOutfile    = flag.String("o", "", "write output to `file`")
-       flagPluginPath = flag.String("pluginpath", "", "full path name for plugin")
-
-       flagInstallSuffix = flag.String("installsuffix", "", "set package directory `suffix`")
-       flagDumpDep       = flag.Bool("dumpdep", false, "dump symbol dependency graph")
-       flagRace          = flag.Bool("race", false, "enable race detector")
-       flagMsan          = flag.Bool("msan", false, "enable MSan interface")
-
-       flagFieldTrack = flag.String("k", "", "set field tracking `symbol`")
-       flagLibGCC     = flag.String("libgcc", "", "compiler support lib for internal linking; use \"none\" to disable")
-       flagTmpdir     = flag.String("tmpdir", "", "use `directory` for temporary files")
-
-       flagExtld      = flag.String("extld", "", "use `linker` when linking in external mode")
-       flagExtldflags = flag.String("extldflags", "", "pass `flags` to external linker")
-       flagExtar      = flag.String("extar", "", "archive program for buildmode=c-archive")
-
-       flagA           = flag.Bool("a", false, "disassemble output")
-       FlagC           = flag.Bool("c", false, "dump call graph")
-       FlagD           = flag.Bool("d", false, "disable dynamic executable")
-       flagF           = flag.Bool("f", false, "ignore version mismatch")
-       flagG           = flag.Bool("g", false, "disable go package data checks")
-       flagH           = flag.Bool("h", false, "halt on error")
-       flagN           = flag.Bool("n", false, "dump symbol table")
-       FlagS           = flag.Bool("s", false, "disable symbol table")
-       flagU           = flag.Bool("u", false, "reject unsafe packages")
-       FlagW           = flag.Bool("w", false, "disable DWARF generation")
-       Flag8           bool // use 64-bit addresses in symbol table
-       flagInterpreter = flag.String("I", "", "use `linker` as ELF dynamic linker")
-       FlagDebugTramp  = flag.Int("debugtramp", 0, "debug trampolines")
-       FlagStrictDups  = flag.Int("strictdups", 0, "sanity check duplicate symbol contents during object file reading (1=warn 2=err).")
-       flagNewobj      = flag.Bool("newobj", false, "use new object file format")
-
-       FlagRound       = flag.Int("R", -1, "set address rounding `quantum`")
-       FlagTextAddr    = flag.Int64("T", -1, "set text segment `address`")
-       flagEntrySymbol = flag.String("E", "", "set `entry` symbol name")
-
-       cpuprofile     = flag.String("cpuprofile", "", "write cpu profile to `file`")
-       memprofile     = flag.String("memprofile", "", "write memory profile to `file`")
-       memprofilerate = flag.Int64("memprofilerate", 0, "set runtime.MemProfileRate to `rate`")
-)
-
-// Main is the main entry point for the linker code.
-func Main(arch *sys.Arch, theArch Arch) {
-       thearch = theArch
-       ctxt := linknew(arch)
-       ctxt.Bso = bufio.NewWriter(os.Stdout)
-
-       // For testing behavior of go command when tools crash silently.
-       // Undocumented, not in standard flag parser to avoid
-       // exposing in usage message.
-       for _, arg := range os.Args {
-               if arg == "-crash_for_testing" {
-                       os.Exit(2)
-               }
-       }
-
-       final := gorootFinal()
-       addstrdata1(ctxt, "runtime/internal/sys.DefaultGoroot="+final)
-       addstrdata1(ctxt, "cmd/internal/objabi.defaultGOROOT="+final)
-
-       // TODO(matloob): define these above and then check flag values here
-       if ctxt.Arch.Family == sys.AMD64 && objabi.GOOS == "plan9" {
-               flag.BoolVar(&Flag8, "8", false, "use 64-bit addresses in symbol table")
-       }
-       flagHeadType := flag.String("H", "", "set header `type`")
-       flag.BoolVar(&ctxt.linkShared, "linkshared", false, "link against installed Go shared libraries")
-       flag.Var(&ctxt.LinkMode, "linkmode", "set link `mode`")
-       flag.Var(&ctxt.BuildMode, "buildmode", "set build `mode`")
-       flag.BoolVar(&ctxt.compressDWARF, "compressdwarf", true, "compress DWARF if possible")
-       objabi.Flagfn1("B", "add an ELF NT_GNU_BUILD_ID `note` when using ELF", addbuildinfo)
-       objabi.Flagfn1("L", "add specified `directory` to library path", func(a string) { Lflag(ctxt, a) })
-       objabi.AddVersionFlag() // -V
-       objabi.Flagfn1("X", "add string value `definition` of the form importpath.name=value", func(s string) { addstrdata1(ctxt, s) })
-       objabi.Flagcount("v", "print link trace", &ctxt.Debugvlog)
-       objabi.Flagfn1("importcfg", "read import configuration from `file`", ctxt.readImportCfg)
-
-       objabi.Flagparse(usage)
-
-       switch *flagHeadType {
-       case "":
-       case "windowsgui":
-               ctxt.HeadType = objabi.Hwindows
-               windowsgui = true
-       default:
-               if err := ctxt.HeadType.Set(*flagHeadType); err != nil {
-                       Errorf(nil, "%v", err)
-                       usage()
-               }
-       }
-
-       if objabi.Fieldtrack_enabled != 0 {
-               ctxt.Reachparent = make(map[*sym.Symbol]*sym.Symbol)
-       }
-       checkStrictDups = *FlagStrictDups
-
-       startProfile()
-       if ctxt.BuildMode == BuildModeUnset {
-               ctxt.BuildMode = BuildModeExe
-       }
-
-       if ctxt.BuildMode != BuildModeShared && flag.NArg() != 1 {
-               usage()
-       }
-
-       if *flagOutfile == "" {
-               *flagOutfile = "a.out"
-               if ctxt.HeadType == objabi.Hwindows {
-                       *flagOutfile += ".exe"
-               }
-       }
-
-       interpreter = *flagInterpreter
-
-       libinit(ctxt) // creates outfile
-
-       if ctxt.HeadType == objabi.Hunknown {
-               ctxt.HeadType.Set(objabi.GOOS)
-       }
-
-       ctxt.computeTLSOffset()
-       thearch.Archinit(ctxt)
-
-       if ctxt.linkShared && !ctxt.IsELF {
-               Exitf("-linkshared can only be used on elf systems")
-       }
-
-       if ctxt.Debugvlog != 0 {
-               ctxt.Logf("HEADER = -H%d -T0x%x -R0x%x\n", ctxt.HeadType, uint64(*FlagTextAddr), uint32(*FlagRound))
-       }
-
-       switch ctxt.BuildMode {
-       case BuildModeShared:
-               for i := 0; i < flag.NArg(); i++ {
-                       arg := flag.Arg(i)
-                       parts := strings.SplitN(arg, "=", 2)
-                       var pkgpath, file string
-                       if len(parts) == 1 {
-                               pkgpath, file = "main", arg
-                       } else {
-                               pkgpath, file = parts[0], parts[1]
-                       }
-                       pkglistfornote = append(pkglistfornote, pkgpath...)
-                       pkglistfornote = append(pkglistfornote, '\n')
-                       addlibpath(ctxt, "command line", "command line", file, pkgpath, "")
-               }
-       case BuildModePlugin:
-               addlibpath(ctxt, "command line", "command line", flag.Arg(0), *flagPluginPath, "")
-       default:
-               addlibpath(ctxt, "command line", "command line", flag.Arg(0), "main", "")
-       }
-       ctxt.loadlib()
-
-       deadcode(ctxt)
-       if *flagNewobj {
-               ctxt.loadlibfull() // XXX do it here for now
-       }
-       ctxt.linksetup()
-       ctxt.dostrdata()
-
-       dwarfGenerateDebugInfo(ctxt)
-       if objabi.Fieldtrack_enabled != 0 {
-               fieldtrack(ctxt)
-       }
-       ctxt.mangleTypeSym()
-       ctxt.callgraph()
-
-       ctxt.doelf()
-       if ctxt.HeadType == objabi.Hdarwin {
-               ctxt.domacho()
-       }
-       ctxt.dostkcheck()
-       if ctxt.HeadType == objabi.Hwindows {
-               ctxt.dope()
-               ctxt.windynrelocsyms()
-       }
-       if ctxt.HeadType == objabi.Haix {
-               ctxt.doxcoff()
-       }
-
-       ctxt.addexport()
-       thearch.Gentext(ctxt) // trampolines, call stubs, etc.
-       ctxt.textbuildid()
-       ctxt.textaddress()
-       ctxt.pclntab()
-       ctxt.findfunctab()
-       ctxt.typelink()
-       ctxt.symtab()
-       ctxt.buildinfo()
-       ctxt.dodata()
-       order := ctxt.address()
-       dwarfcompress(ctxt)
-       filesize := ctxt.layout(order)
-
-       // Write out the output file.
-       // It is split into two parts (Asmb and Asmb2). The first
-       // part writes most of the content (sections and segments),
-       // for which we have computed the size and offset, in a
-       // mmap'd region. The second part writes more content, for
-       // which we don't know the size.
-       var outputMmapped bool
-       if ctxt.Arch.Family != sys.Wasm {
-               // Don't mmap if we're building for Wasm. Wasm file
-               // layout is very different so filesize is meaningless.
-               err := ctxt.Out.Mmap(filesize)
-               outputMmapped = err == nil
-       }
-       if outputMmapped {
-               // Asmb will redirect symbols to the output file mmap, and relocations
-               // will be applied directly there.
-               thearch.Asmb(ctxt)
-               ctxt.reloc()
-               ctxt.Out.Munmap()
-       } else {
-               // If we don't mmap, we need to apply relocations before
-               // writing out.
-               ctxt.reloc()
-               thearch.Asmb(ctxt)
-       }
-       thearch.Asmb2(ctxt)
-
-       ctxt.undef()
-       ctxt.hostlink()
-       if ctxt.Debugvlog != 0 {
-               ctxt.Logf("%d symbols\n", len(ctxt.Syms.Allsym))
-               ctxt.Logf("%d liveness data\n", liveness)
-       }
-       ctxt.Bso.Flush()
-       ctxt.archive()
-
-       errorexit()
-}
-
-type Rpath struct {
-       set bool
-       val string
-}
-
-func (r *Rpath) Set(val string) error {
-       r.set = true
-       r.val = val
-       return nil
-}
-
-func (r *Rpath) String() string {
-       return r.val
-}
-
-func startProfile() {
-       if *cpuprofile != "" {
-               f, err := os.Create(*cpuprofile)
-               if err != nil {
-                       log.Fatalf("%v", err)
-               }
-               if err := pprof.StartCPUProfile(f); err != nil {
-                       log.Fatalf("%v", err)
-               }
-               AtExit(pprof.StopCPUProfile)
-       }
-       if *memprofile != "" {
-               if *memprofilerate != 0 {
-                       runtime.MemProfileRate = int(*memprofilerate)
-               }
-               f, err := os.Create(*memprofile)
-               if err != nil {
-                       log.Fatalf("%v", err)
-               }
-               AtExit(func() {
-                       // Profile all outstanding allocations.
-                       runtime.GC()
-                       // compilebench parses the memory profile to extract memstats,
-                       // which are only written in the legacy pprof format.
-                       // See golang.org/issue/18641 and runtime/pprof/pprof.go:writeHeap.
-                       const writeLegacyFormat = 1
-                       if err := pprof.Lookup("heap").WriteTo(f, writeLegacyFormat); err != nil {
-                               log.Fatalf("%v", err)
-                       }
-               })
-       }
-}
diff --git a/src/cmd/oldlink/internal/ld/outbuf.go b/src/cmd/oldlink/internal/ld/outbuf.go
deleted file mode 100644 (file)
index 596d239..0000000
+++ /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 (file)
index 4075141..0000000
+++ /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 (file)
index fba8cd8..0000000
+++ /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 (file)
index 1cb05c3..0000000
+++ /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 (file)
index 7d53ab8..0000000
+++ /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 (file)
index b40557f..0000000
+++ /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 (file)
index 4f697d0..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-// Derived from Inferno utils/6l/obj.c and utils/6l/span.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ld
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/sym"
-       "log"
-)
-
-func linknew(arch *sys.Arch) *Link {
-       ctxt := &Link{
-               Syms:         sym.NewSymbols(),
-               Out:          &OutBuf{arch: arch},
-               Arch:         arch,
-               LibraryByPkg: make(map[string]*sym.Library),
-       }
-
-       if objabi.GOARCH != arch.Name {
-               log.Fatalf("invalid objabi.GOARCH %s (want %s)", objabi.GOARCH, arch.Name)
-       }
-
-       AtExit(func() {
-               if nerrors > 0 && ctxt.Out.f != nil {
-                       ctxt.Out.f.Close()
-                       mayberemoveoutfile()
-               }
-       })
-
-       return ctxt
-}
-
-// computeTLSOffset records the thread-local storage offset.
-// Not used for Android where the TLS offset is determined at runtime.
-func (ctxt *Link) computeTLSOffset() {
-       switch ctxt.HeadType {
-       default:
-               log.Fatalf("unknown thread-local storage offset for %v", ctxt.HeadType)
-
-       case objabi.Hplan9, objabi.Hwindows, objabi.Hjs, objabi.Haix:
-               break
-
-       case objabi.Hlinux,
-               objabi.Hfreebsd,
-               objabi.Hnetbsd,
-               objabi.Hopenbsd,
-               objabi.Hdragonfly,
-               objabi.Hsolaris:
-               /*
-                * ELF uses TLS offset negative from FS.
-                * Translate 0(FS) and 8(FS) into -16(FS) and -8(FS).
-                * Known to low-level assembly in package runtime and runtime/cgo.
-                */
-               ctxt.Tlsoffset = -1 * ctxt.Arch.PtrSize
-
-       case objabi.Hdarwin:
-               /*
-                * OS X system constants - offset from 0(GS) to our TLS.
-                */
-               switch ctxt.Arch.Family {
-               default:
-                       log.Fatalf("unknown thread-local storage offset for darwin/%s", ctxt.Arch.Name)
-
-                       /*
-                        * For x86, Apple has reserved a slot in the TLS for Go. See issue 23617.
-                        * That slot is at offset 0x30 on amd64.
-                        * The slot will hold the G pointer.
-                        * These constants should match those in runtime/sys_darwin_{386,amd64}.s
-                        * and runtime/cgo/gcc_darwin_{386,amd64}.c.
-                        */
-               case sys.AMD64:
-                       ctxt.Tlsoffset = 0x30
-
-               case sys.ARM64:
-                       ctxt.Tlsoffset = 0 // dummy value, not needed
-               }
-       }
-
-}
diff --git a/src/cmd/oldlink/internal/ld/symtab.go b/src/cmd/oldlink/internal/ld/symtab.go
deleted file mode 100644 (file)
index a324fdf..0000000
+++ /dev/null
@@ -1,713 +0,0 @@
-// Inferno utils/6l/span.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ld
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/sym"
-       "fmt"
-       "path/filepath"
-       "strings"
-)
-
-// Symbol table.
-
-func putelfstr(s string) int {
-       if len(Elfstrdat) == 0 && s != "" {
-               // first entry must be empty string
-               putelfstr("")
-       }
-
-       off := len(Elfstrdat)
-       Elfstrdat = append(Elfstrdat, s...)
-       Elfstrdat = append(Elfstrdat, 0)
-       return off
-}
-
-func putelfsyment(out *OutBuf, off int, addr int64, size int64, info int, shndx int, other int) {
-       if elf64 {
-               out.Write32(uint32(off))
-               out.Write8(uint8(info))
-               out.Write8(uint8(other))
-               out.Write16(uint16(shndx))
-               out.Write64(uint64(addr))
-               out.Write64(uint64(size))
-               Symsize += ELF64SYMSIZE
-       } else {
-               out.Write32(uint32(off))
-               out.Write32(uint32(addr))
-               out.Write32(uint32(size))
-               out.Write8(uint8(info))
-               out.Write8(uint8(other))
-               out.Write16(uint16(shndx))
-               Symsize += ELF32SYMSIZE
-       }
-}
-
-var numelfsym = 1 // 0 is reserved
-
-var elfbind int
-
-func putelfsym(ctxt *Link, x *sym.Symbol, s string, t SymbolType, addr int64, go_ *sym.Symbol) {
-       var typ int
-
-       switch t {
-       default:
-               return
-
-       case TextSym:
-               typ = STT_FUNC
-
-       case DataSym, BSSSym:
-               typ = STT_OBJECT
-
-       case UndefinedSym:
-               // ElfType is only set for symbols read from Go shared libraries, but
-               // for other symbols it is left as STT_NOTYPE which is fine.
-               typ = int(x.ElfType())
-
-       case TLSSym:
-               typ = STT_TLS
-       }
-
-       size := x.Size
-       if t == UndefinedSym {
-               size = 0
-       }
-
-       xo := x
-       for xo.Outer != nil {
-               xo = xo.Outer
-       }
-
-       var elfshnum int
-       if xo.Type == sym.SDYNIMPORT || xo.Type == sym.SHOSTOBJ || xo.Type == sym.SUNDEFEXT {
-               elfshnum = SHN_UNDEF
-       } else {
-               if xo.Sect == nil {
-                       Errorf(x, "missing section in putelfsym")
-                       return
-               }
-               if xo.Sect.Elfsect == nil {
-                       Errorf(x, "missing ELF section in putelfsym")
-                       return
-               }
-               elfshnum = xo.Sect.Elfsect.(*ElfShdr).shnum
-       }
-
-       // One pass for each binding: STB_LOCAL, STB_GLOBAL,
-       // maybe one day STB_WEAK.
-       bind := STB_GLOBAL
-
-       if x.IsFileLocal() || x.Attr.VisibilityHidden() || x.Attr.Local() {
-               bind = STB_LOCAL
-       }
-
-       // In external linking mode, we have to invoke gcc with -rdynamic
-       // to get the exported symbols put into the dynamic symbol table.
-       // To avoid filling the dynamic table with lots of unnecessary symbols,
-       // mark all Go symbols local (not global) in the final executable.
-       // But when we're dynamically linking, we need all those global symbols.
-       if !ctxt.DynlinkingGo() && ctxt.LinkMode == LinkExternal && !x.Attr.CgoExportStatic() && elfshnum != SHN_UNDEF {
-               bind = STB_LOCAL
-       }
-
-       if ctxt.LinkMode == LinkExternal && elfshnum != SHN_UNDEF {
-               addr -= int64(xo.Sect.Vaddr)
-       }
-       other := STV_DEFAULT
-       if x.Attr.VisibilityHidden() {
-               // TODO(mwhudson): We only set AttrVisibilityHidden in ldelf, i.e. when
-               // internally linking. But STV_HIDDEN visibility only matters in object
-               // files and shared libraries, and as we are a long way from implementing
-               // internal linking for shared libraries and only create object files when
-               // externally linking, I don't think this makes a lot of sense.
-               other = STV_HIDDEN
-       }
-       if ctxt.Arch.Family == sys.PPC64 && typ == STT_FUNC && x.Attr.Shared() && x.Name != "runtime.duffzero" && x.Name != "runtime.duffcopy" {
-               // On ppc64 the top three bits of the st_other field indicate how
-               // many instructions separate the global and local entry points. In
-               // our case it is two instructions, indicated by the value 3.
-               // The conditions here match those in preprocess in
-               // cmd/internal/obj/ppc64/obj9.go, which is where the
-               // instructions are inserted.
-               other |= 3 << 5
-       }
-
-       // When dynamically linking, we create Symbols by reading the names from
-       // the symbol tables of the shared libraries and so the names need to
-       // match exactly. Tools like DTrace will have to wait for now.
-       if !ctxt.DynlinkingGo() {
-               // Rewrite · to . for ASCII-only tools like DTrace (sigh)
-               s = strings.Replace(s, "·", ".", -1)
-       }
-
-       if ctxt.DynlinkingGo() && bind == STB_GLOBAL && elfbind == STB_LOCAL && x.Type == sym.STEXT {
-               // When dynamically linking, we want references to functions defined
-               // in this module to always be to the function object, not to the
-               // PLT. We force this by writing an additional local symbol for every
-               // global function symbol and making all relocations against the
-               // global symbol refer to this local symbol instead (see
-               // (*sym.Symbol).ElfsymForReloc). This is approximately equivalent to the
-               // ELF linker -Bsymbolic-functions option, but that is buggy on
-               // several platforms.
-               putelfsyment(ctxt.Out, putelfstr("local."+s), addr, size, STB_LOCAL<<4|typ&0xf, elfshnum, other)
-               x.LocalElfsym = int32(numelfsym)
-               numelfsym++
-               return
-       } else if bind != elfbind {
-               return
-       }
-
-       putelfsyment(ctxt.Out, putelfstr(s), addr, size, bind<<4|typ&0xf, elfshnum, other)
-       x.Elfsym = int32(numelfsym)
-       numelfsym++
-}
-
-func putelfsectionsym(out *OutBuf, s *sym.Symbol, shndx int) {
-       putelfsyment(out, 0, 0, 0, STB_LOCAL<<4|STT_SECTION, shndx, 0)
-       s.Elfsym = int32(numelfsym)
-       numelfsym++
-}
-
-func Asmelfsym(ctxt *Link) {
-       // the first symbol entry is reserved
-       putelfsyment(ctxt.Out, 0, 0, 0, STB_LOCAL<<4|STT_NOTYPE, 0, 0)
-
-       dwarfaddelfsectionsyms(ctxt)
-
-       // Some linkers will add a FILE sym if one is not present.
-       // Avoid having the working directory inserted into the symbol table.
-       // It is added with a name to avoid problems with external linking
-       // encountered on some versions of Solaris. See issue #14957.
-       putelfsyment(ctxt.Out, putelfstr("go.go"), 0, 0, STB_LOCAL<<4|STT_FILE, SHN_ABS, 0)
-       numelfsym++
-
-       elfbind = STB_LOCAL
-       genasmsym(ctxt, putelfsym)
-
-       elfbind = STB_GLOBAL
-       elfglobalsymndx = numelfsym
-       genasmsym(ctxt, putelfsym)
-}
-
-func putplan9sym(ctxt *Link, x *sym.Symbol, s string, typ SymbolType, addr int64, go_ *sym.Symbol) {
-       t := int(typ)
-       switch typ {
-       case TextSym, DataSym, BSSSym:
-               if x.IsFileLocal() {
-                       t += 'a' - 'A'
-               }
-               fallthrough
-
-       case AutoSym, ParamSym, FrameSym:
-               l := 4
-               if ctxt.HeadType == objabi.Hplan9 && ctxt.Arch.Family == sys.AMD64 && !Flag8 {
-                       ctxt.Out.Write32b(uint32(addr >> 32))
-                       l = 8
-               }
-
-               ctxt.Out.Write32b(uint32(addr))
-               ctxt.Out.Write8(uint8(t + 0x80)) /* 0x80 is variable length */
-
-               ctxt.Out.WriteString(s)
-               ctxt.Out.Write8(0)
-
-               Symsize += int32(l) + 1 + int32(len(s)) + 1
-
-       default:
-               return
-       }
-}
-
-func Asmplan9sym(ctxt *Link) {
-       genasmsym(ctxt, putplan9sym)
-}
-
-var symt *sym.Symbol
-
-type byPkg []*sym.Library
-
-func (libs byPkg) Len() int {
-       return len(libs)
-}
-
-func (libs byPkg) Less(a, b int) bool {
-       return libs[a].Pkg < libs[b].Pkg
-}
-
-func (libs byPkg) Swap(a, b int) {
-       libs[a], libs[b] = libs[b], libs[a]
-}
-
-// Create a table with information on the text sections.
-
-func textsectionmap(ctxt *Link) uint32 {
-
-       t := ctxt.Syms.Lookup("runtime.textsectionmap", 0)
-       t.Type = sym.SRODATA
-       t.Attr |= sym.AttrReachable
-       nsections := int64(0)
-
-       for _, sect := range Segtext.Sections {
-               if sect.Name == ".text" {
-                       nsections++
-               } else {
-                       break
-               }
-       }
-       t.Grow(3 * nsections * int64(ctxt.Arch.PtrSize))
-
-       off := int64(0)
-       n := 0
-
-       // The vaddr for each text section is the difference between the section's
-       // Vaddr and the Vaddr for the first text section as determined at compile
-       // time.
-
-       // The symbol for the first text section is named runtime.text as before.
-       // Additional text sections are named runtime.text.n where n is the
-       // order of creation starting with 1. These symbols provide the section's
-       // address after relocation by the linker.
-
-       textbase := Segtext.Sections[0].Vaddr
-       for _, sect := range Segtext.Sections {
-               if sect.Name != ".text" {
-                       break
-               }
-               off = t.SetUint(ctxt.Arch, off, sect.Vaddr-textbase)
-               off = t.SetUint(ctxt.Arch, off, sect.Length)
-               if n == 0 {
-                       s := ctxt.Syms.ROLookup("runtime.text", 0)
-                       if s == nil {
-                               Errorf(nil, "Unable to find symbol runtime.text\n")
-                       }
-                       off = t.SetAddr(ctxt.Arch, off, s)
-
-               } else {
-                       s := ctxt.Syms.Lookup(fmt.Sprintf("runtime.text.%d", n), 0)
-                       if s == nil {
-                               Errorf(nil, "Unable to find symbol runtime.text.%d\n", n)
-                       }
-                       off = t.SetAddr(ctxt.Arch, off, s)
-               }
-               n++
-       }
-       return uint32(n)
-}
-
-func (ctxt *Link) symtab() {
-       switch ctxt.BuildMode {
-       case BuildModeCArchive, BuildModeCShared:
-               for _, s := range ctxt.Syms.Allsym {
-                       // Create a new entry in the .init_array section that points to the
-                       // library initializer function.
-                       if s.Name == *flagEntrySymbol && ctxt.HeadType != objabi.Haix {
-                               addinitarrdata(ctxt, s)
-                       }
-               }
-       }
-
-       // Define these so that they'll get put into the symbol table.
-       // data.c:/^address will provide the actual values.
-       ctxt.xdefine("runtime.text", sym.STEXT, 0)
-
-       ctxt.xdefine("runtime.etext", sym.STEXT, 0)
-       ctxt.xdefine("runtime.itablink", sym.SRODATA, 0)
-       ctxt.xdefine("runtime.eitablink", sym.SRODATA, 0)
-       ctxt.xdefine("runtime.rodata", sym.SRODATA, 0)
-       ctxt.xdefine("runtime.erodata", sym.SRODATA, 0)
-       ctxt.xdefine("runtime.types", sym.SRODATA, 0)
-       ctxt.xdefine("runtime.etypes", sym.SRODATA, 0)
-       ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, 0)
-       ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, 0)
-       ctxt.xdefine("runtime.data", sym.SDATA, 0)
-       ctxt.xdefine("runtime.edata", sym.SDATA, 0)
-       ctxt.xdefine("runtime.bss", sym.SBSS, 0)
-       ctxt.xdefine("runtime.ebss", sym.SBSS, 0)
-       ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, 0)
-       ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, 0)
-       ctxt.xdefine("runtime.end", sym.SBSS, 0)
-       ctxt.xdefine("runtime.epclntab", sym.SRODATA, 0)
-       ctxt.xdefine("runtime.esymtab", sym.SRODATA, 0)
-
-       // garbage collection symbols
-       s := ctxt.Syms.Lookup("runtime.gcdata", 0)
-
-       s.Type = sym.SRODATA
-       s.Size = 0
-       s.Attr |= sym.AttrReachable
-       ctxt.xdefine("runtime.egcdata", sym.SRODATA, 0)
-
-       s = ctxt.Syms.Lookup("runtime.gcbss", 0)
-       s.Type = sym.SRODATA
-       s.Size = 0
-       s.Attr |= sym.AttrReachable
-       ctxt.xdefine("runtime.egcbss", sym.SRODATA, 0)
-
-       // pseudo-symbols to mark locations of type, string, and go string data.
-       var symtype *sym.Symbol
-       var symtyperel *sym.Symbol
-       if !ctxt.DynlinkingGo() {
-               if ctxt.UseRelro() && (ctxt.BuildMode == BuildModeCArchive || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE) {
-                       s = ctxt.Syms.Lookup("type.*", 0)
-
-                       s.Type = sym.STYPE
-                       s.Size = 0
-                       s.Attr |= sym.AttrReachable
-                       symtype = s
-
-                       s = ctxt.Syms.Lookup("typerel.*", 0)
-
-                       s.Type = sym.STYPERELRO
-                       s.Size = 0
-                       s.Attr |= sym.AttrReachable
-                       symtyperel = s
-               } else {
-                       s = ctxt.Syms.Lookup("type.*", 0)
-
-                       s.Type = sym.STYPE
-                       s.Size = 0
-                       s.Attr |= sym.AttrReachable
-                       symtype = s
-                       symtyperel = s
-               }
-       }
-
-       groupSym := func(name string, t sym.SymKind) *sym.Symbol {
-               s := ctxt.Syms.Lookup(name, 0)
-               s.Type = t
-               s.Size = 0
-               s.Attr |= sym.AttrLocal | sym.AttrReachable
-               return s
-       }
-       var (
-               symgostring = groupSym("go.string.*", sym.SGOSTRING)
-               symgofunc   = groupSym("go.func.*", sym.SGOFUNC)
-               symgcbits   = groupSym("runtime.gcbits.*", sym.SGCBITS)
-       )
-
-       var symgofuncrel *sym.Symbol
-       if !ctxt.DynlinkingGo() {
-               if ctxt.UseRelro() {
-                       symgofuncrel = groupSym("go.funcrel.*", sym.SGOFUNCRELRO)
-               } else {
-                       symgofuncrel = symgofunc
-               }
-       }
-
-       symitablink := ctxt.Syms.Lookup("runtime.itablink", 0)
-       symitablink.Type = sym.SITABLINK
-
-       symt = ctxt.Syms.Lookup("runtime.symtab", 0)
-       symt.Attr |= sym.AttrLocal
-       symt.Type = sym.SSYMTAB
-       symt.Size = 0
-       symt.Attr |= sym.AttrReachable
-
-       nitablinks := 0
-
-       // assign specific types so that they sort together.
-       // within a type they sort by size, so the .* symbols
-       // just defined above will be first.
-       // hide the specific symbols.
-       for _, s := range ctxt.Syms.Allsym {
-               if ctxt.LinkMode != LinkExternal && isStaticTemp(s.Name) {
-                       s.Attr |= sym.AttrNotInSymbolTable
-               }
-
-               if !s.Attr.Reachable() || s.Attr.Special() || s.Type != sym.SRODATA {
-                       continue
-               }
-
-               switch {
-               case strings.HasPrefix(s.Name, "type."):
-                       if !ctxt.DynlinkingGo() {
-                               s.Attr |= sym.AttrNotInSymbolTable
-                       }
-                       if ctxt.UseRelro() {
-                               s.Type = sym.STYPERELRO
-                               s.Outer = symtyperel
-                       } else {
-                               s.Type = sym.STYPE
-                               s.Outer = symtype
-                       }
-
-               case strings.HasPrefix(s.Name, "go.importpath.") && ctxt.UseRelro():
-                       // Keep go.importpath symbols in the same section as types and
-                       // names, as they can be referred to by a section offset.
-                       s.Type = sym.STYPERELRO
-
-               case strings.HasPrefix(s.Name, "go.itablink."):
-                       nitablinks++
-                       s.Type = sym.SITABLINK
-                       s.Attr |= sym.AttrNotInSymbolTable
-                       s.Outer = symitablink
-
-               case strings.HasPrefix(s.Name, "go.string."):
-                       s.Type = sym.SGOSTRING
-                       s.Attr |= sym.AttrNotInSymbolTable
-                       s.Outer = symgostring
-
-               case strings.HasPrefix(s.Name, "runtime.gcbits."):
-                       s.Type = sym.SGCBITS
-                       s.Attr |= sym.AttrNotInSymbolTable
-                       s.Outer = symgcbits
-
-               case strings.HasSuffix(s.Name, "·f"):
-                       if !ctxt.DynlinkingGo() {
-                               s.Attr |= sym.AttrNotInSymbolTable
-                       }
-                       if ctxt.UseRelro() {
-                               s.Type = sym.SGOFUNCRELRO
-                               s.Outer = symgofuncrel
-                       } else {
-                               s.Type = sym.SGOFUNC
-                               s.Outer = symgofunc
-                       }
-
-               case strings.HasPrefix(s.Name, "gcargs."),
-                       strings.HasPrefix(s.Name, "gclocals."),
-                       strings.HasPrefix(s.Name, "gclocals·"),
-                       strings.HasPrefix(s.Name, "inltree."),
-                       strings.HasSuffix(s.Name, ".opendefer"):
-                       s.Type = sym.SGOFUNC
-                       s.Attr |= sym.AttrNotInSymbolTable
-                       s.Outer = symgofunc
-                       s.Align = 4
-                       liveness += (s.Size + int64(s.Align) - 1) &^ (int64(s.Align) - 1)
-               }
-       }
-
-       if ctxt.BuildMode == BuildModeShared {
-               abihashgostr := ctxt.Syms.Lookup("go.link.abihash."+filepath.Base(*flagOutfile), 0)
-               abihashgostr.Attr |= sym.AttrReachable
-               abihashgostr.Type = sym.SRODATA
-               hashsym := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
-               abihashgostr.AddAddr(ctxt.Arch, hashsym)
-               abihashgostr.AddUint(ctxt.Arch, uint64(hashsym.Size))
-       }
-       if ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
-               for _, l := range ctxt.Library {
-                       s := ctxt.Syms.Lookup("go.link.pkghashbytes."+l.Pkg, 0)
-                       s.Attr |= sym.AttrReachable
-                       s.Type = sym.SRODATA
-                       s.Size = int64(len(l.Hash))
-                       s.P = []byte(l.Hash)
-                       str := ctxt.Syms.Lookup("go.link.pkghash."+l.Pkg, 0)
-                       str.Attr |= sym.AttrReachable
-                       str.Type = sym.SRODATA
-                       str.AddAddr(ctxt.Arch, s)
-                       str.AddUint(ctxt.Arch, uint64(len(l.Hash)))
-               }
-       }
-
-       nsections := textsectionmap(ctxt)
-
-       // Information about the layout of the executable image for the
-       // runtime to use. Any changes here must be matched by changes to
-       // the definition of moduledata in runtime/symtab.go.
-       // This code uses several global variables that are set by pcln.go:pclntab.
-       moduledata := ctxt.Moduledata
-       // The pclntab slice
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.pclntab", 0))
-       moduledata.AddUint(ctxt.Arch, uint64(ctxt.Syms.Lookup("runtime.pclntab", 0).Size))
-       moduledata.AddUint(ctxt.Arch, uint64(ctxt.Syms.Lookup("runtime.pclntab", 0).Size))
-       // The ftab slice
-       moduledata.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup("runtime.pclntab", 0), int64(pclntabPclntabOffset))
-       moduledata.AddUint(ctxt.Arch, uint64(pclntabNfunc+1))
-       moduledata.AddUint(ctxt.Arch, uint64(pclntabNfunc+1))
-       // The filetab slice
-       moduledata.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup("runtime.pclntab", 0), int64(pclntabFiletabOffset))
-       moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Filesyms))+1)
-       moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Filesyms))+1)
-       // findfunctab
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.findfunctab", 0))
-       // minpc, maxpc
-       moduledata.AddAddr(ctxt.Arch, pclntabFirstFunc)
-       moduledata.AddAddrPlus(ctxt.Arch, pclntabLastFunc, pclntabLastFunc.Size)
-       // pointers to specific parts of the module
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.text", 0))
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.etext", 0))
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.noptrdata", 0))
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.enoptrdata", 0))
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.data", 0))
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.edata", 0))
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.bss", 0))
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.ebss", 0))
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.noptrbss", 0))
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.enoptrbss", 0))
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.end", 0))
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.gcdata", 0))
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.gcbss", 0))
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.types", 0))
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.etypes", 0))
-
-       if ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal {
-               // Add R_REF relocation to prevent ld's garbage collection of
-               // runtime.rodata, runtime.erodata and runtime.epclntab.
-               addRef := func(name string) {
-                       r := moduledata.AddRel()
-                       r.Sym = ctxt.Syms.Lookup(name, 0)
-                       r.Type = objabi.R_XCOFFREF
-                       r.Siz = uint8(ctxt.Arch.PtrSize)
-               }
-               addRef("runtime.rodata")
-               addRef("runtime.erodata")
-               addRef("runtime.epclntab")
-       }
-
-       // text section information
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.textsectionmap", 0))
-       moduledata.AddUint(ctxt.Arch, uint64(nsections))
-       moduledata.AddUint(ctxt.Arch, uint64(nsections))
-
-       // The typelinks slice
-       typelinkSym := ctxt.Syms.Lookup("runtime.typelink", 0)
-       ntypelinks := uint64(typelinkSym.Size) / 4
-       moduledata.AddAddr(ctxt.Arch, typelinkSym)
-       moduledata.AddUint(ctxt.Arch, ntypelinks)
-       moduledata.AddUint(ctxt.Arch, ntypelinks)
-       // The itablinks slice
-       moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.itablink", 0))
-       moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
-       moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
-       // The ptab slice
-       if ptab := ctxt.Syms.ROLookup("go.plugin.tabs", 0); ptab != nil && ptab.Attr.Reachable() {
-               ptab.Attr |= sym.AttrLocal
-               ptab.Type = sym.SRODATA
-
-               nentries := uint64(len(ptab.P) / 8) // sizeof(nameOff) + sizeof(typeOff)
-               moduledata.AddAddr(ctxt.Arch, ptab)
-               moduledata.AddUint(ctxt.Arch, nentries)
-               moduledata.AddUint(ctxt.Arch, nentries)
-       } else {
-               moduledata.AddUint(ctxt.Arch, 0)
-               moduledata.AddUint(ctxt.Arch, 0)
-               moduledata.AddUint(ctxt.Arch, 0)
-       }
-       if ctxt.BuildMode == BuildModePlugin {
-               addgostring(ctxt, moduledata, "go.link.thispluginpath", objabi.PathToPrefix(*flagPluginPath))
-
-               pkghashes := ctxt.Syms.Lookup("go.link.pkghashes", 0)
-               pkghashes.Attr |= sym.AttrReachable
-               pkghashes.Attr |= sym.AttrLocal
-               pkghashes.Type = sym.SRODATA
-
-               for i, l := range ctxt.Library {
-                       // pkghashes[i].name
-                       addgostring(ctxt, pkghashes, fmt.Sprintf("go.link.pkgname.%d", i), l.Pkg)
-                       // pkghashes[i].linktimehash
-                       addgostring(ctxt, pkghashes, fmt.Sprintf("go.link.pkglinkhash.%d", i), l.Hash)
-                       // pkghashes[i].runtimehash
-                       hash := ctxt.Syms.ROLookup("go.link.pkghash."+l.Pkg, 0)
-                       pkghashes.AddAddr(ctxt.Arch, hash)
-               }
-               moduledata.AddAddr(ctxt.Arch, pkghashes)
-               moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Library)))
-               moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Library)))
-       } else {
-               moduledata.AddUint(ctxt.Arch, 0) // pluginpath
-               moduledata.AddUint(ctxt.Arch, 0)
-               moduledata.AddUint(ctxt.Arch, 0) // pkghashes slice
-               moduledata.AddUint(ctxt.Arch, 0)
-               moduledata.AddUint(ctxt.Arch, 0)
-       }
-       if len(ctxt.Shlibs) > 0 {
-               thismodulename := filepath.Base(*flagOutfile)
-               switch ctxt.BuildMode {
-               case BuildModeExe, BuildModePIE:
-                       // When linking an executable, outfile is just "a.out". Make
-                       // it something slightly more comprehensible.
-                       thismodulename = "the executable"
-               }
-               addgostring(ctxt, moduledata, "go.link.thismodulename", thismodulename)
-
-               modulehashes := ctxt.Syms.Lookup("go.link.abihashes", 0)
-               modulehashes.Attr |= sym.AttrReachable
-               modulehashes.Attr |= sym.AttrLocal
-               modulehashes.Type = sym.SRODATA
-
-               for i, shlib := range ctxt.Shlibs {
-                       // modulehashes[i].modulename
-                       modulename := filepath.Base(shlib.Path)
-                       addgostring(ctxt, modulehashes, fmt.Sprintf("go.link.libname.%d", i), modulename)
-
-                       // modulehashes[i].linktimehash
-                       addgostring(ctxt, modulehashes, fmt.Sprintf("go.link.linkhash.%d", i), string(shlib.Hash))
-
-                       // modulehashes[i].runtimehash
-                       abihash := ctxt.Syms.Lookup("go.link.abihash."+modulename, 0)
-                       abihash.Attr |= sym.AttrReachable
-                       modulehashes.AddAddr(ctxt.Arch, abihash)
-               }
-
-               moduledata.AddAddr(ctxt.Arch, modulehashes)
-               moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Shlibs)))
-               moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Shlibs)))
-       } else {
-               moduledata.AddUint(ctxt.Arch, 0) // modulename
-               moduledata.AddUint(ctxt.Arch, 0)
-               moduledata.AddUint(ctxt.Arch, 0) // moduleshashes slice
-               moduledata.AddUint(ctxt.Arch, 0)
-               moduledata.AddUint(ctxt.Arch, 0)
-       }
-
-       hasmain := ctxt.BuildMode == BuildModeExe || ctxt.BuildMode == BuildModePIE
-       if hasmain {
-               moduledata.AddUint8(1)
-       } else {
-               moduledata.AddUint8(0)
-       }
-
-       // The rest of moduledata is zero initialized.
-       // When linking an object that does not contain the runtime we are
-       // creating the moduledata from scratch and it does not have a
-       // compiler-provided size, so read it from the type data.
-       moduledatatype := ctxt.Syms.ROLookup("type.runtime.moduledata", 0)
-       moduledata.Size = decodetypeSize(ctxt.Arch, moduledatatype.P)
-       moduledata.Grow(moduledata.Size)
-
-       lastmoduledatap := ctxt.Syms.Lookup("runtime.lastmoduledatap", 0)
-       if lastmoduledatap.Type != sym.SDYNIMPORT {
-               lastmoduledatap.Type = sym.SNOPTRDATA
-               lastmoduledatap.Size = 0 // overwrite existing value
-               lastmoduledatap.AddAddr(ctxt.Arch, moduledata)
-       }
-}
-
-func isStaticTemp(name string) bool {
-       if i := strings.LastIndex(name, "/"); i >= 0 {
-               name = name[i:]
-       }
-       return strings.Contains(name, "..stmp_")
-}
diff --git a/src/cmd/oldlink/internal/ld/testdata/httptest/main/main.go b/src/cmd/oldlink/internal/ld/testdata/httptest/main/main.go
deleted file mode 100644 (file)
index 1bce301..0000000
+++ /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 (file)
index 5e8c097..0000000
+++ /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 (file)
index 1d00e76..0000000
+++ /dev/null
@@ -1 +0,0 @@
-// This file is needed to make "go build" work for package with external functions.\r
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 (file)
index 6032d76..0000000
+++ /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 (file)
index 3f5f365..0000000
+++ /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 (file)
index ca57749..0000000
+++ /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 (file)
index 88b54f1..0000000
+++ /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 (file)
index 9462788..0000000
+++ /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 (file)
index 514b9b9..0000000
+++ /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 (file)
index 9eec6cc..0000000
+++ /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 (file)
index 07d04bb..0000000
+++ /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 (file)
index 97c9a44..0000000
+++ /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 (file)
index 4d66d6d..0000000
+++ /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 (file)
index db37db9..0000000
+++ /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 (file)
index 8c618bf..0000000
+++ /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 (file)
index 4846239..0000000
+++ /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 (file)
index f7df774..0000000
+++ /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 (file)
index 832b168..0000000
+++ /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 (file)
index 48a2324..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2016 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package mips
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/ld"
-       "cmd/oldlink/internal/sym"
-       "debug/elf"
-       "fmt"
-       "log"
-)
-
-func gentext(ctxt *ld.Link) {
-       return
-}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-       log.Fatalf("adddynrel not implemented")
-       return false
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-       ctxt.Out.Write32(uint32(sectoff))
-
-       elfsym := r.Xsym.ElfsymForReloc()
-       switch r.Type {
-       default:
-               return false
-       case objabi.R_ADDR:
-               if r.Siz != 4 {
-                       return false
-               }
-               ctxt.Out.Write32(uint32(elf.R_MIPS_32) | uint32(elfsym)<<8)
-       case objabi.R_ADDRMIPS:
-               ctxt.Out.Write32(uint32(elf.R_MIPS_LO16) | uint32(elfsym)<<8)
-       case objabi.R_ADDRMIPSU:
-               ctxt.Out.Write32(uint32(elf.R_MIPS_HI16) | uint32(elfsym)<<8)
-       case objabi.R_ADDRMIPSTLS:
-               ctxt.Out.Write32(uint32(elf.R_MIPS_TLS_TPREL_LO16) | uint32(elfsym)<<8)
-       case objabi.R_CALLMIPS, objabi.R_JMPMIPS:
-               ctxt.Out.Write32(uint32(elf.R_MIPS_26) | uint32(elfsym)<<8)
-       }
-
-       return true
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-       return
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-       return false
-}
-
-func applyrel(arch *sys.Arch, r *sym.Reloc, s *sym.Symbol, val int64, t int64) int64 {
-       o := arch.ByteOrder.Uint32(s.P[r.Off:])
-       switch r.Type {
-       case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSTLS:
-               return int64(o&0xffff0000 | uint32(t)&0xffff)
-       case objabi.R_ADDRMIPSU:
-               return int64(o&0xffff0000 | uint32((t+(1<<15))>>16)&0xffff)
-       case objabi.R_CALLMIPS, objabi.R_JMPMIPS:
-               return int64(o&0xfc000000 | uint32(t>>2)&^0xfc000000)
-       default:
-               return val
-       }
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-       if ctxt.LinkMode == ld.LinkExternal {
-               switch r.Type {
-               default:
-                       return val, false
-               case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSU:
-                       r.Done = false
-
-                       // set up addend for eventual relocation via outer symbol.
-                       rs := r.Sym
-                       r.Xadd = r.Add
-                       for rs.Outer != nil {
-                               r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
-                               rs = rs.Outer
-                       }
-
-                       if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
-                               ld.Errorf(s, "missing section for %s", rs.Name)
-                       }
-                       r.Xsym = rs
-                       return applyrel(ctxt.Arch, r, s, val, r.Xadd), true
-               case objabi.R_ADDRMIPSTLS, objabi.R_CALLMIPS, objabi.R_JMPMIPS:
-                       r.Done = false
-                       r.Xsym = r.Sym
-                       r.Xadd = r.Add
-                       return applyrel(ctxt.Arch, r, s, val, r.Add), true
-               }
-       }
-
-       switch r.Type {
-       case objabi.R_CONST:
-               return r.Add, true
-       case objabi.R_GOTOFF:
-               return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
-       case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSU:
-               t := ld.Symaddr(r.Sym) + r.Add
-               return applyrel(ctxt.Arch, r, s, val, t), true
-       case objabi.R_CALLMIPS, objabi.R_JMPMIPS:
-               t := ld.Symaddr(r.Sym) + r.Add
-
-               if t&3 != 0 {
-                       ld.Errorf(s, "direct call is not aligned: %s %x", r.Sym.Name, t)
-               }
-
-               // check if target address is in the same 256 MB region as the next instruction
-               if (s.Value+int64(r.Off)+4)&0xf0000000 != (t & 0xf0000000) {
-                       ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
-               }
-
-               return applyrel(ctxt.Arch, r, s, val, t), true
-       case objabi.R_ADDRMIPSTLS:
-               // thread pointer is at 0x7000 offset from the start of TLS data area
-               t := ld.Symaddr(r.Sym) + r.Add - 0x7000
-               if t < -32768 || t >= 32678 {
-                       ld.Errorf(s, "TLS offset out of range %d", t)
-               }
-               return applyrel(ctxt.Arch, r, s, val, t), true
-       }
-
-       return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-       return -1
-}
-
-func asmb(ctxt *ld.Link) {
-       if ctxt.IsELF {
-               ld.Asmbelfsetup()
-       }
-
-       sect := ld.Segtext.Sections[0]
-       ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-       ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-       for _, sect = range ld.Segtext.Sections[1:] {
-               ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-               ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-       }
-
-       if ld.Segrodata.Filelen > 0 {
-               ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-               ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-       }
-
-       ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-       ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-       ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-       ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-       /* output symbol table */
-       ld.Symsize = 0
-
-       ld.Lcsize = 0
-       symo := uint32(0)
-       if !*ld.FlagS {
-               if !ctxt.IsELF {
-                       ld.Errorf(nil, "unsupported executable format")
-               }
-               symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-               symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
-
-               ctxt.Out.SeekSet(int64(symo))
-               ld.Asmelfsym(ctxt)
-               ctxt.Out.Flush()
-               ctxt.Out.Write(ld.Elfstrdat)
-
-               if ctxt.LinkMode == ld.LinkExternal {
-                       ld.Elfemitreloc(ctxt)
-               }
-       }
-
-       ctxt.Out.SeekSet(0)
-       switch ctxt.HeadType {
-       default:
-               ld.Errorf(nil, "unsupported operating system")
-       case objabi.Hlinux:
-               ld.Asmbelf(ctxt, int64(symo))
-       }
-
-       ctxt.Out.Flush()
-       if *ld.FlagC {
-               fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
-               fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
-               fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
-               fmt.Printf("symsize=%d\n", ld.Symsize)
-               fmt.Printf("lcsize=%d\n", ld.Lcsize)
-               fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
-       }
-}
diff --git a/src/cmd/oldlink/internal/mips/l.go b/src/cmd/oldlink/internal/mips/l.go
deleted file mode 100644 (file)
index adbde40..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2016 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package mips
-
-// Writing object files.
-
-// cmd/9l/l.h from Vita Nuova.
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
-//     Portions Copyright © 2016 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-const (
-       MaxAlign  = 32 // max data alignment
-       MinAlign  = 1  // min data alignment
-       FuncAlign = 4
-)
-
-/* Used by ../internal/ld/dwarf.go */
-const (
-       DWARFREGSP = 29
-       DWARFREGLR = 31
-)
diff --git a/src/cmd/oldlink/internal/mips/obj.go b/src/cmd/oldlink/internal/mips/obj.go
deleted file mode 100644 (file)
index c80824f..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-// Inferno utils/5l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/obj.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2016 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package mips
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-       arch := sys.ArchMIPS
-       if objabi.GOARCH == "mipsle" {
-               arch = sys.ArchMIPSLE
-       }
-
-       theArch := ld.Arch{
-               Funcalign:  FuncAlign,
-               Maxalign:   MaxAlign,
-               Minalign:   MinAlign,
-               Dwarfregsp: DWARFREGSP,
-               Dwarfreglr: DWARFREGLR,
-
-               Adddynrel:        adddynrel,
-               Archinit:         archinit,
-               Archreloc:        archreloc,
-               Archrelocvariant: archrelocvariant,
-               Asmb:             asmb,
-               Asmb2:            asmb2,
-               Elfreloc1:        elfreloc1,
-               Elfsetupplt:      elfsetupplt,
-               Gentext:          gentext,
-               Machoreloc1:      machoreloc1,
-
-               Linuxdynld: "/lib/ld.so.1",
-
-               Freebsddynld:   "XXX",
-               Openbsddynld:   "XXX",
-               Netbsddynld:    "XXX",
-               Dragonflydynld: "XXX",
-               Solarisdynld:   "XXX",
-       }
-
-       return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-       switch ctxt.HeadType {
-       default:
-               ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-       case objabi.Hlinux: /* mips elf */
-               ld.Elfinit(ctxt)
-               ld.HEADR = ld.ELFRESERVE
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
-               }
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 0x10000
-               }
-       }
-}
diff --git a/src/cmd/oldlink/internal/mips64/asm.go b/src/cmd/oldlink/internal/mips64/asm.go
deleted file mode 100644 (file)
index 775b74e..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package mips64
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/ld"
-       "cmd/oldlink/internal/sym"
-       "debug/elf"
-       "fmt"
-       "log"
-)
-
-func gentext(ctxt *ld.Link) {}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-       log.Fatalf("adddynrel not implemented")
-       return false
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-       // mips64 ELF relocation (endian neutral)
-       //              offset  uint64
-       //              sym             uint32
-       //              ssym    uint8
-       //              type3   uint8
-       //              type2   uint8
-       //              type    uint8
-       //              addend  int64
-
-       ctxt.Out.Write64(uint64(sectoff))
-
-       elfsym := r.Xsym.ElfsymForReloc()
-       ctxt.Out.Write32(uint32(elfsym))
-       ctxt.Out.Write8(0)
-       ctxt.Out.Write8(0)
-       ctxt.Out.Write8(0)
-       switch r.Type {
-       default:
-               return false
-       case objabi.R_ADDR:
-               switch r.Siz {
-               case 4:
-                       ctxt.Out.Write8(uint8(elf.R_MIPS_32))
-               case 8:
-                       ctxt.Out.Write8(uint8(elf.R_MIPS_64))
-               default:
-                       return false
-               }
-       case objabi.R_ADDRMIPS:
-               ctxt.Out.Write8(uint8(elf.R_MIPS_LO16))
-       case objabi.R_ADDRMIPSU:
-               ctxt.Out.Write8(uint8(elf.R_MIPS_HI16))
-       case objabi.R_ADDRMIPSTLS:
-               ctxt.Out.Write8(uint8(elf.R_MIPS_TLS_TPREL_LO16))
-       case objabi.R_CALLMIPS,
-               objabi.R_JMPMIPS:
-               ctxt.Out.Write8(uint8(elf.R_MIPS_26))
-       }
-       ctxt.Out.Write64(uint64(r.Xadd))
-
-       return true
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-       return
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-       return false
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-       if ctxt.LinkMode == ld.LinkExternal {
-               switch r.Type {
-               default:
-                       return val, false
-               case objabi.R_ADDRMIPS,
-                       objabi.R_ADDRMIPSU:
-                       r.Done = false
-
-                       // set up addend for eventual relocation via outer symbol.
-                       rs := r.Sym
-                       r.Xadd = r.Add
-                       for rs.Outer != nil {
-                               r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
-                               rs = rs.Outer
-                       }
-
-                       if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
-                               ld.Errorf(s, "missing section for %s", rs.Name)
-                       }
-                       r.Xsym = rs
-
-                       return val, true
-               case objabi.R_ADDRMIPSTLS,
-                       objabi.R_CALLMIPS,
-                       objabi.R_JMPMIPS:
-                       r.Done = false
-                       r.Xsym = r.Sym
-                       r.Xadd = r.Add
-                       return val, true
-               }
-       }
-
-       switch r.Type {
-       case objabi.R_CONST:
-               return r.Add, true
-       case objabi.R_GOTOFF:
-               return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
-       case objabi.R_ADDRMIPS,
-               objabi.R_ADDRMIPSU:
-               t := ld.Symaddr(r.Sym) + r.Add
-               o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
-               if r.Type == objabi.R_ADDRMIPS {
-                       return int64(o1&0xffff0000 | uint32(t)&0xffff), true
-               }
-               return int64(o1&0xffff0000 | uint32((t+1<<15)>>16)&0xffff), true
-       case objabi.R_ADDRMIPSTLS:
-               // thread pointer is at 0x7000 offset from the start of TLS data area
-               t := ld.Symaddr(r.Sym) + r.Add - 0x7000
-               if t < -32768 || t >= 32678 {
-                       ld.Errorf(s, "TLS offset out of range %d", t)
-               }
-               o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
-               return int64(o1&0xffff0000 | uint32(t)&0xffff), true
-       case objabi.R_CALLMIPS,
-               objabi.R_JMPMIPS:
-               // Low 26 bits = (S + A) >> 2
-               t := ld.Symaddr(r.Sym) + r.Add
-               o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
-               return int64(o1&0xfc000000 | uint32(t>>2)&^0xfc000000), true
-       }
-
-       return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-       return -1
-}
-
-func asmb(ctxt *ld.Link) {
-       if ctxt.IsELF {
-               ld.Asmbelfsetup()
-       }
-
-       sect := ld.Segtext.Sections[0]
-       ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-       ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-       for _, sect = range ld.Segtext.Sections[1:] {
-               ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-               ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-       }
-
-       if ld.Segrodata.Filelen > 0 {
-               ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-               ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-       }
-       if ld.Segrelrodata.Filelen > 0 {
-               ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
-               ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
-       }
-
-       ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-       ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-       ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-       ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-       /* output symbol table */
-       ld.Symsize = 0
-
-       ld.Lcsize = 0
-       symo := uint32(0)
-       if !*ld.FlagS {
-               // TODO: rationalize
-               switch ctxt.HeadType {
-               default:
-                       if ctxt.IsELF {
-                               symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-                               symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
-                       }
-
-               case objabi.Hplan9:
-                       symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
-               }
-
-               ctxt.Out.SeekSet(int64(symo))
-               switch ctxt.HeadType {
-               default:
-                       if ctxt.IsELF {
-                               ld.Asmelfsym(ctxt)
-                               ctxt.Out.Flush()
-                               ctxt.Out.Write(ld.Elfstrdat)
-
-                               if ctxt.LinkMode == ld.LinkExternal {
-                                       ld.Elfemitreloc(ctxt)
-                               }
-                       }
-
-               case objabi.Hplan9:
-                       ld.Asmplan9sym(ctxt)
-                       ctxt.Out.Flush()
-
-                       sym := ctxt.Syms.Lookup("pclntab", 0)
-                       if sym != nil {
-                               ld.Lcsize = int32(len(sym.P))
-                               ctxt.Out.Write(sym.P)
-                               ctxt.Out.Flush()
-                       }
-               }
-       }
-
-       ctxt.Out.SeekSet(0)
-       switch ctxt.HeadType {
-       default:
-       case objabi.Hplan9: /* plan 9 */
-               magic := uint32(4*18*18 + 7)
-               if ctxt.Arch == sys.ArchMIPS64LE {
-                       magic = uint32(4*26*26 + 7)
-               }
-               ctxt.Out.Write32(magic)                      /* magic */
-               ctxt.Out.Write32(uint32(ld.Segtext.Filelen)) /* sizes */
-               ctxt.Out.Write32(uint32(ld.Segdata.Filelen))
-               ctxt.Out.Write32(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-               ctxt.Out.Write32(uint32(ld.Symsize))          /* nsyms */
-               ctxt.Out.Write32(uint32(ld.Entryvalue(ctxt))) /* va of entry */
-               ctxt.Out.Write32(0)
-               ctxt.Out.Write32(uint32(ld.Lcsize))
-
-       case objabi.Hlinux,
-               objabi.Hfreebsd,
-               objabi.Hnetbsd,
-               objabi.Hopenbsd:
-               ld.Asmbelf(ctxt, int64(symo))
-       }
-
-       ctxt.Out.Flush()
-       if *ld.FlagC {
-               fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
-               fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
-               fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
-               fmt.Printf("symsize=%d\n", ld.Symsize)
-               fmt.Printf("lcsize=%d\n", ld.Lcsize)
-               fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
-       }
-}
diff --git a/src/cmd/oldlink/internal/mips64/l.go b/src/cmd/oldlink/internal/mips64/l.go
deleted file mode 100644 (file)
index d794122..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package mips64
-
-// Writing object files.
-
-// cmd/9l/l.h from Vita Nuova.
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-const (
-       maxAlign  = 32 // max data alignment
-       minAlign  = 1  // min data alignment
-       funcAlign = 8
-)
-
-/* Used by ../internal/ld/dwarf.go */
-const (
-       dwarfRegSP = 29
-       dwarfRegLR = 31
-)
diff --git a/src/cmd/oldlink/internal/mips64/obj.go b/src/cmd/oldlink/internal/mips64/obj.go
deleted file mode 100644 (file)
index 1ddce45..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-// Inferno utils/5l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/obj.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package mips64
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-       arch := sys.ArchMIPS64
-       if objabi.GOARCH == "mips64le" {
-               arch = sys.ArchMIPS64LE
-       }
-
-       theArch := ld.Arch{
-               Funcalign:        funcAlign,
-               Maxalign:         maxAlign,
-               Minalign:         minAlign,
-               Dwarfregsp:       dwarfRegSP,
-               Dwarfreglr:       dwarfRegLR,
-               Adddynrel:        adddynrel,
-               Archinit:         archinit,
-               Archreloc:        archreloc,
-               Archrelocvariant: archrelocvariant,
-               Asmb:             asmb,
-               Asmb2:            asmb2,
-               Elfreloc1:        elfreloc1,
-               Elfsetupplt:      elfsetupplt,
-               Gentext:          gentext,
-               Machoreloc1:      machoreloc1,
-
-               Linuxdynld:     "/lib64/ld64.so.1",
-               Freebsddynld:   "XXX",
-               Openbsddynld:   "XXX",
-               Netbsddynld:    "XXX",
-               Dragonflydynld: "XXX",
-               Solarisdynld:   "XXX",
-       }
-
-       return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-       switch ctxt.HeadType {
-       default:
-               ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-
-       case objabi.Hplan9: /* plan 9 */
-               ld.HEADR = 32
-
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = 16*1024 + int64(ld.HEADR)
-               }
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 16 * 1024
-               }
-
-       case objabi.Hlinux: /* mips64 elf */
-               ld.Elfinit(ctxt)
-               ld.HEADR = ld.ELFRESERVE
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
-               }
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 0x10000
-               }
-       }
-}
diff --git a/src/cmd/oldlink/internal/objfile/objfile.go b/src/cmd/oldlink/internal/objfile/objfile.go
deleted file mode 100644 (file)
index 6882b76..0000000
+++ /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 (file)
index 608bdec..0000000
+++ /dev/null
@@ -1,1181 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ppc64
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/ld"
-       "cmd/oldlink/internal/sym"
-       "debug/elf"
-       "encoding/binary"
-       "fmt"
-       "log"
-       "strings"
-)
-
-func genplt(ctxt *ld.Link) {
-       // The ppc64 ABI PLT has similar concepts to other
-       // architectures, but is laid out quite differently. When we
-       // see an R_PPC64_REL24 relocation to a dynamic symbol
-       // (indicating that the call needs to go through the PLT), we
-       // generate up to three stubs and reserve a PLT slot.
-       //
-       // 1) The call site will be bl x; nop (where the relocation
-       //    applies to the bl).  We rewrite this to bl x_stub; ld
-       //    r2,24(r1).  The ld is necessary because x_stub will save
-       //    r2 (the TOC pointer) at 24(r1) (the "TOC save slot").
-       //
-       // 2) We reserve space for a pointer in the .plt section (once
-       //    per referenced dynamic function).  .plt is a data
-       //    section filled solely by the dynamic linker (more like
-       //    .plt.got on other architectures).  Initially, the
-       //    dynamic linker will fill each slot with a pointer to the
-       //    corresponding x@plt entry point.
-       //
-       // 3) We generate the "call stub" x_stub (once per dynamic
-       //    function/object file pair).  This saves the TOC in the
-       //    TOC save slot, reads the function pointer from x's .plt
-       //    slot and calls it like any other global entry point
-       //    (including setting r12 to the function address).
-       //
-       // 4) We generate the "symbol resolver stub" x@plt (once per
-       //    dynamic function).  This is solely a branch to the glink
-       //    resolver stub.
-       //
-       // 5) We generate the glink resolver stub (only once).  This
-       //    computes which symbol resolver stub we came through and
-       //    invokes the dynamic resolver via a pointer provided by
-       //    the dynamic linker. This will patch up the .plt slot to
-       //    point directly at the function so future calls go
-       //    straight from the call stub to the real function, and
-       //    then call the function.
-
-       // NOTE: It's possible we could make ppc64 closer to other
-       // architectures: ppc64's .plt is like .plt.got on other
-       // platforms and ppc64's .glink is like .plt on other
-       // platforms.
-
-       // Find all R_PPC64_REL24 relocations that reference dynamic
-       // imports. Reserve PLT entries for these symbols and
-       // generate call stubs. The call stubs need to live in .text,
-       // which is why we need to do this pass this early.
-       //
-       // This assumes "case 1" from the ABI, where the caller needs
-       // us to save and restore the TOC pointer.
-       var stubs []*sym.Symbol
-       for _, s := range ctxt.Textp {
-               for i := range s.R {
-                       r := &s.R[i]
-                       if r.Type != objabi.ElfRelocOffset+objabi.RelocType(elf.R_PPC64_REL24) || r.Sym.Type != sym.SDYNIMPORT {
-                               continue
-                       }
-
-                       // Reserve PLT entry and generate symbol
-                       // resolver
-                       addpltsym(ctxt, r.Sym)
-
-                       // Generate call stub
-                       n := fmt.Sprintf("%s.%s", s.Name, r.Sym.Name)
-
-                       stub := ctxt.Syms.Lookup(n, 0)
-                       if s.Attr.Reachable() {
-                               stub.Attr |= sym.AttrReachable
-                       }
-                       if stub.Size == 0 {
-                               // Need outer to resolve .TOC.
-                               stub.Outer = s
-                               stubs = append(stubs, stub)
-                               gencallstub(ctxt, 1, stub, r.Sym)
-                       }
-
-                       // Update the relocation to use the call stub
-                       r.Sym = stub
-
-                       // Restore TOC after bl. The compiler put a
-                       // nop here for us to overwrite.
-                       const o1 = 0xe8410018 // ld r2,24(r1)
-                       ctxt.Arch.ByteOrder.PutUint32(s.P[r.Off+4:], o1)
-               }
-       }
-       // Put call stubs at the beginning (instead of the end).
-       // So when resolving the relocations to calls to the stubs,
-       // the addresses are known and trampolines can be inserted
-       // when necessary.
-       ctxt.Textp = append(stubs, ctxt.Textp...)
-}
-
-func genaddmoduledata(ctxt *ld.Link) {
-       addmoduledata := ctxt.Syms.ROLookup("runtime.addmoduledata", sym.SymVerABI0)
-       if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
-               return
-       }
-       addmoduledata.Attr |= sym.AttrReachable
-       initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-       initfunc.Type = sym.STEXT
-       initfunc.Attr |= sym.AttrLocal
-       initfunc.Attr |= sym.AttrReachable
-       o := func(op uint32) {
-               initfunc.AddUint32(ctxt.Arch, op)
-       }
-       // addis r2, r12, .TOC.-func@ha
-       rel := initfunc.AddRel()
-       rel.Off = int32(initfunc.Size)
-       rel.Siz = 8
-       rel.Sym = ctxt.Syms.Lookup(".TOC.", 0)
-       rel.Sym.Attr |= sym.AttrReachable
-       rel.Type = objabi.R_ADDRPOWER_PCREL
-       o(0x3c4c0000)
-       // addi r2, r2, .TOC.-func@l
-       o(0x38420000)
-       // mflr r31
-       o(0x7c0802a6)
-       // stdu r31, -32(r1)
-       o(0xf801ffe1)
-       // addis r3, r2, local.moduledata@got@ha
-       rel = initfunc.AddRel()
-       rel.Off = int32(initfunc.Size)
-       rel.Siz = 8
-       if s := ctxt.Syms.ROLookup("local.moduledata", 0); s != nil {
-               rel.Sym = s
-       } else if s := ctxt.Syms.ROLookup("local.pluginmoduledata", 0); s != nil {
-               rel.Sym = s
-       } else {
-               rel.Sym = ctxt.Syms.Lookup("runtime.firstmoduledata", 0)
-       }
-       rel.Sym.Attr |= sym.AttrReachable
-       rel.Sym.Attr |= sym.AttrLocal
-       rel.Type = objabi.R_ADDRPOWER_GOT
-       o(0x3c620000)
-       // ld r3, local.moduledata@got@l(r3)
-       o(0xe8630000)
-       // bl runtime.addmoduledata
-       rel = initfunc.AddRel()
-       rel.Off = int32(initfunc.Size)
-       rel.Siz = 4
-       rel.Sym = addmoduledata
-       rel.Type = objabi.R_CALLPOWER
-       o(0x48000001)
-       // nop
-       o(0x60000000)
-       // ld r31, 0(r1)
-       o(0xe8010000)
-       // mtlr r31
-       o(0x7c0803a6)
-       // addi r1,r1,32
-       o(0x38210020)
-       // blr
-       o(0x4e800020)
-
-       if ctxt.BuildMode == ld.BuildModePlugin {
-               ctxt.Textp = append(ctxt.Textp, addmoduledata)
-       }
-       initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-       ctxt.Textp = append(ctxt.Textp, initfunc)
-       initarray_entry.Attr |= sym.AttrReachable
-       initarray_entry.Attr |= sym.AttrLocal
-       initarray_entry.Type = sym.SINITARR
-       initarray_entry.AddAddr(ctxt.Arch, initfunc)
-}
-
-func gentext(ctxt *ld.Link) {
-       if ctxt.DynlinkingGo() {
-               genaddmoduledata(ctxt)
-       }
-
-       if ctxt.LinkMode == ld.LinkInternal {
-               genplt(ctxt)
-       }
-}
-
-// Construct a call stub in stub that calls symbol targ via its PLT
-// entry.
-func gencallstub(ctxt *ld.Link, abicase int, stub *sym.Symbol, targ *sym.Symbol) {
-       if abicase != 1 {
-               // If we see R_PPC64_TOCSAVE or R_PPC64_REL24_NOTOC
-               // relocations, we'll need to implement cases 2 and 3.
-               log.Fatalf("gencallstub only implements case 1 calls")
-       }
-
-       plt := ctxt.Syms.Lookup(".plt", 0)
-
-       stub.Type = sym.STEXT
-
-       // Save TOC pointer in TOC save slot
-       stub.AddUint32(ctxt.Arch, 0xf8410018) // std r2,24(r1)
-
-       // Load the function pointer from the PLT.
-       r := stub.AddRel()
-
-       r.Off = int32(stub.Size)
-       r.Sym = plt
-       r.Add = int64(targ.Plt())
-       r.Siz = 2
-       if ctxt.Arch.ByteOrder == binary.BigEndian {
-               r.Off += int32(r.Siz)
-       }
-       r.Type = objabi.R_POWER_TOC
-       r.Variant = sym.RV_POWER_HA
-       stub.AddUint32(ctxt.Arch, 0x3d820000) // addis r12,r2,targ@plt@toc@ha
-       r = stub.AddRel()
-       r.Off = int32(stub.Size)
-       r.Sym = plt
-       r.Add = int64(targ.Plt())
-       r.Siz = 2
-       if ctxt.Arch.ByteOrder == binary.BigEndian {
-               r.Off += int32(r.Siz)
-       }
-       r.Type = objabi.R_POWER_TOC
-       r.Variant = sym.RV_POWER_LO
-       stub.AddUint32(ctxt.Arch, 0xe98c0000) // ld r12,targ@plt@toc@l(r12)
-
-       // Jump to the loaded pointer
-       stub.AddUint32(ctxt.Arch, 0x7d8903a6) // mtctr r12
-       stub.AddUint32(ctxt.Arch, 0x4e800420) // bctr
-}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-       if ctxt.IsELF {
-               return addelfdynrel(ctxt, s, r)
-       } else if ctxt.HeadType == objabi.Haix {
-               return ld.Xcoffadddynrel(ctxt, s, r)
-       }
-       return false
-}
-func addelfdynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-       targ := r.Sym
-       r.InitExt()
-
-       switch r.Type {
-       default:
-               if r.Type >= objabi.ElfRelocOffset {
-                       ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
-                       return false
-               }
-
-               // Handle relocations found in ELF object files.
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL24):
-               r.Type = objabi.R_CALLPOWER
-
-               // This is a local call, so the caller isn't setting
-               // up r12 and r2 is the same for the caller and
-               // callee. Hence, we need to go to the local entry
-               // point.  (If we don't do this, the callee will try
-               // to use r12 to compute r2.)
-               r.Add += int64(r.Sym.Localentry()) * 4
-
-               if targ.Type == sym.SDYNIMPORT {
-                       // Should have been handled in elfsetupplt
-                       ld.Errorf(s, "unexpected R_PPC64_REL24 for dyn import")
-               }
-
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC_REL32):
-               r.Type = objabi.R_PCREL
-               r.Add += 4
-
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected R_PPC_REL32 for dyn import")
-               }
-
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_ADDR64):
-               r.Type = objabi.R_ADDR
-               if targ.Type == sym.SDYNIMPORT {
-                       // These happen in .toc sections
-                       ld.Adddynsym(ctxt, targ)
-
-                       rela := ctxt.Syms.Lookup(".rela", 0)
-                       rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
-                       rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_PPC64_ADDR64)))
-                       rela.AddUint64(ctxt.Arch, uint64(r.Add))
-                       r.Type = objabi.ElfRelocOffset // ignore during relocsym
-               }
-
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16):
-               r.Type = objabi.R_POWER_TOC
-               r.Variant = sym.RV_POWER_LO | sym.RV_CHECK_OVERFLOW
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_LO):
-               r.Type = objabi.R_POWER_TOC
-               r.Variant = sym.RV_POWER_LO
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_HA):
-               r.Type = objabi.R_POWER_TOC
-               r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_HI):
-               r.Type = objabi.R_POWER_TOC
-               r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_DS):
-               r.Type = objabi.R_POWER_TOC
-               r.Variant = sym.RV_POWER_DS | sym.RV_CHECK_OVERFLOW
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_LO_DS):
-               r.Type = objabi.R_POWER_TOC
-               r.Variant = sym.RV_POWER_DS
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL16_LO):
-               r.Type = objabi.R_PCREL
-               r.Variant = sym.RV_POWER_LO
-               r.Add += 2 // Compensate for relocation size of 2
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL16_HI):
-               r.Type = objabi.R_PCREL
-               r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW
-               r.Add += 2
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL16_HA):
-               r.Type = objabi.R_PCREL
-               r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW
-               r.Add += 2
-               return true
-       }
-
-       // Handle references to ELF symbols from our own object files.
-       if targ.Type != sym.SDYNIMPORT {
-               return true
-       }
-
-       // TODO(austin): Translate our relocations to ELF
-
-       return false
-}
-
-func xcoffreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-       rs := r.Xsym
-
-       emitReloc := func(v uint16, off uint64) {
-               out.Write64(uint64(sectoff) + off)
-               out.Write32(uint32(rs.Dynid))
-               out.Write16(v)
-       }
-
-       var v uint16
-       switch r.Type {
-       default:
-               return false
-       case objabi.R_ADDR:
-               v = ld.XCOFF_R_POS
-               if r.Siz == 4 {
-                       v |= 0x1F << 8
-               } else {
-                       v |= 0x3F << 8
-               }
-               emitReloc(v, 0)
-       case objabi.R_ADDRPOWER_TOCREL:
-       case objabi.R_ADDRPOWER_TOCREL_DS:
-               emitReloc(ld.XCOFF_R_TOCU|(0x0F<<8), 2)
-               emitReloc(ld.XCOFF_R_TOCL|(0x0F<<8), 6)
-       case objabi.R_POWER_TLS_LE:
-               emitReloc(ld.XCOFF_R_TLS_LE|0x0F<<8, 2)
-       case objabi.R_CALLPOWER:
-               if r.Siz != 4 {
-                       return false
-               }
-               emitReloc(ld.XCOFF_R_RBR|0x19<<8, 0)
-       case objabi.R_XCOFFREF:
-               emitReloc(ld.XCOFF_R_REF|0x3F<<8, 0)
-
-       }
-       return true
-
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-       // Beware that bit0~bit15 start from the third byte of a instruction in Big-Endian machines.
-       if r.Type == objabi.R_ADDR || r.Type == objabi.R_POWER_TLS || r.Type == objabi.R_CALLPOWER {
-       } else {
-               if ctxt.Arch.ByteOrder == binary.BigEndian {
-                       sectoff += 2
-               }
-       }
-       ctxt.Out.Write64(uint64(sectoff))
-
-       elfsym := r.Xsym.ElfsymForReloc()
-       switch r.Type {
-       default:
-               return false
-       case objabi.R_ADDR:
-               switch r.Siz {
-               case 4:
-                       ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR32) | uint64(elfsym)<<32)
-               case 8:
-                       ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR64) | uint64(elfsym)<<32)
-               default:
-                       return false
-               }
-       case objabi.R_POWER_TLS:
-               ctxt.Out.Write64(uint64(elf.R_PPC64_TLS) | uint64(elfsym)<<32)
-       case objabi.R_POWER_TLS_LE:
-               ctxt.Out.Write64(uint64(elf.R_PPC64_TPREL16) | uint64(elfsym)<<32)
-       case objabi.R_POWER_TLS_IE:
-               ctxt.Out.Write64(uint64(elf.R_PPC64_GOT_TPREL16_HA) | uint64(elfsym)<<32)
-               ctxt.Out.Write64(uint64(r.Xadd))
-               ctxt.Out.Write64(uint64(sectoff + 4))
-               ctxt.Out.Write64(uint64(elf.R_PPC64_GOT_TPREL16_LO_DS) | uint64(elfsym)<<32)
-       case objabi.R_ADDRPOWER:
-               ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR16_HA) | uint64(elfsym)<<32)
-               ctxt.Out.Write64(uint64(r.Xadd))
-               ctxt.Out.Write64(uint64(sectoff + 4))
-               ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR16_LO) | uint64(elfsym)<<32)
-       case objabi.R_ADDRPOWER_DS:
-               ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR16_HA) | uint64(elfsym)<<32)
-               ctxt.Out.Write64(uint64(r.Xadd))
-               ctxt.Out.Write64(uint64(sectoff + 4))
-               ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR16_LO_DS) | uint64(elfsym)<<32)
-       case objabi.R_ADDRPOWER_GOT:
-               ctxt.Out.Write64(uint64(elf.R_PPC64_GOT16_HA) | uint64(elfsym)<<32)
-               ctxt.Out.Write64(uint64(r.Xadd))
-               ctxt.Out.Write64(uint64(sectoff + 4))
-               ctxt.Out.Write64(uint64(elf.R_PPC64_GOT16_LO_DS) | uint64(elfsym)<<32)
-       case objabi.R_ADDRPOWER_PCREL:
-               ctxt.Out.Write64(uint64(elf.R_PPC64_REL16_HA) | uint64(elfsym)<<32)
-               ctxt.Out.Write64(uint64(r.Xadd))
-               ctxt.Out.Write64(uint64(sectoff + 4))
-               ctxt.Out.Write64(uint64(elf.R_PPC64_REL16_LO) | uint64(elfsym)<<32)
-               r.Xadd += 4
-       case objabi.R_ADDRPOWER_TOCREL:
-               ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_HA) | uint64(elfsym)<<32)
-               ctxt.Out.Write64(uint64(r.Xadd))
-               ctxt.Out.Write64(uint64(sectoff + 4))
-               ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_LO) | uint64(elfsym)<<32)
-       case objabi.R_ADDRPOWER_TOCREL_DS:
-               ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_HA) | uint64(elfsym)<<32)
-               ctxt.Out.Write64(uint64(r.Xadd))
-               ctxt.Out.Write64(uint64(sectoff + 4))
-               ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_LO_DS) | uint64(elfsym)<<32)
-       case objabi.R_CALLPOWER:
-               if r.Siz != 4 {
-                       return false
-               }
-               ctxt.Out.Write64(uint64(elf.R_PPC64_REL24) | uint64(elfsym)<<32)
-
-       }
-       ctxt.Out.Write64(uint64(r.Xadd))
-
-       return true
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-       plt := ctxt.Syms.Lookup(".plt", 0)
-       if plt.Size == 0 {
-               // The dynamic linker stores the address of the
-               // dynamic resolver and the DSO identifier in the two
-               // doublewords at the beginning of the .plt section
-               // before the PLT array. Reserve space for these.
-               plt.Size = 16
-       }
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-       return false
-}
-
-// Return the value of .TOC. for symbol s
-func symtoc(ctxt *ld.Link, s *sym.Symbol) int64 {
-       var toc *sym.Symbol
-
-       if s.Outer != nil {
-               toc = ctxt.Syms.ROLookup(".TOC.", int(s.Outer.Version))
-       } else {
-               toc = ctxt.Syms.ROLookup(".TOC.", int(s.Version))
-       }
-
-       if toc == nil {
-               ld.Errorf(s, "TOC-relative relocation in object without .TOC.")
-               return 0
-       }
-
-       return toc.Value
-}
-
-// archreloctoc relocates a TOC relative symbol.
-// If the symbol pointed by this TOC relative symbol is in .data or .bss, the
-// default load instruction can be changed to an addi instruction and the
-// symbol address can be used directly.
-// This code is for AIX only.
-func archreloctoc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) int64 {
-       if ctxt.HeadType == objabi.Hlinux {
-               ld.Errorf(s, "archrelocaddr called for %s relocation\n", r.Sym.Name)
-       }
-       var o1, o2 uint32
-
-       o1 = uint32(val >> 32)
-       o2 = uint32(val)
-
-       var t int64
-       useAddi := false
-       const prefix = "TOC."
-       var tarSym *sym.Symbol
-       if strings.HasPrefix(r.Sym.Name, prefix) {
-               tarSym = r.Sym.R[0].Sym
-       } else {
-               ld.Errorf(s, "archreloctoc called for a symbol without TOC anchor")
-       }
-
-       if ctxt.LinkMode == ld.LinkInternal && tarSym != nil && tarSym.Attr.Reachable() && (tarSym.Sect.Seg == &ld.Segdata) {
-               t = ld.Symaddr(tarSym) + r.Add - ctxt.Syms.ROLookup("TOC", 0).Value
-               // change ld to addi in the second instruction
-               o2 = (o2 & 0x03FF0000) | 0xE<<26
-               useAddi = true
-       } else {
-               t = ld.Symaddr(r.Sym) + r.Add - ctxt.Syms.ROLookup("TOC", 0).Value
-       }
-
-       if t != int64(int32(t)) {
-               ld.Errorf(s, "TOC relocation for %s is too big to relocate %s: 0x%x", s.Name, r.Sym, t)
-       }
-
-       if t&0x8000 != 0 {
-               t += 0x10000
-       }
-
-       o1 |= uint32((t >> 16) & 0xFFFF)
-
-       switch r.Type {
-       case objabi.R_ADDRPOWER_TOCREL_DS:
-               if useAddi {
-                       o2 |= uint32(t) & 0xFFFF
-               } else {
-                       if t&3 != 0 {
-                               ld.Errorf(s, "bad DS reloc for %s: %d", s.Name, ld.Symaddr(r.Sym))
-                       }
-                       o2 |= uint32(t) & 0xFFFC
-               }
-       default:
-               return -1
-       }
-
-       return int64(o1)<<32 | int64(o2)
-}
-
-// archrelocaddr relocates a symbol address.
-// This code is for AIX only.
-func archrelocaddr(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) int64 {
-       if ctxt.HeadType == objabi.Haix {
-               ld.Errorf(s, "archrelocaddr called for %s relocation\n", r.Sym.Name)
-       }
-       var o1, o2 uint32
-       if ctxt.Arch.ByteOrder == binary.BigEndian {
-               o1 = uint32(val >> 32)
-               o2 = uint32(val)
-       } else {
-               o1 = uint32(val)
-               o2 = uint32(val >> 32)
-       }
-
-       // We are spreading a 31-bit address across two instructions, putting the
-       // high (adjusted) part in the low 16 bits of the first instruction and the
-       // low part in the low 16 bits of the second instruction, or, in the DS case,
-       // bits 15-2 (inclusive) of the address into bits 15-2 of the second
-       // instruction (it is an error in this case if the low 2 bits of the address
-       // are non-zero).
-
-       t := ld.Symaddr(r.Sym) + r.Add
-       if t < 0 || t >= 1<<31 {
-               ld.Errorf(s, "relocation for %s is too big (>=2G): 0x%x", s.Name, ld.Symaddr(r.Sym))
-       }
-       if t&0x8000 != 0 {
-               t += 0x10000
-       }
-
-       switch r.Type {
-       case objabi.R_ADDRPOWER:
-               o1 |= (uint32(t) >> 16) & 0xffff
-               o2 |= uint32(t) & 0xffff
-       case objabi.R_ADDRPOWER_DS:
-               o1 |= (uint32(t) >> 16) & 0xffff
-               if t&3 != 0 {
-                       ld.Errorf(s, "bad DS reloc for %s: %d", s.Name, ld.Symaddr(r.Sym))
-               }
-               o2 |= uint32(t) & 0xfffc
-       default:
-               return -1
-       }
-
-       if ctxt.Arch.ByteOrder == binary.BigEndian {
-               return int64(o1)<<32 | int64(o2)
-       }
-       return int64(o2)<<32 | int64(o1)
-}
-
-// resolve direct jump relocation r in s, and add trampoline if necessary
-func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
-
-       // Trampolines are created if the branch offset is too large and the linker cannot insert a call stub to handle it.
-       // For internal linking, trampolines are always created for long calls.
-       // For external linking, the linker can insert a call stub to handle a long call, but depends on having the TOC address in
-       // r2.  For those build modes with external linking where the TOC address is not maintained in r2, trampolines must be created.
-       if ctxt.LinkMode == ld.LinkExternal && (ctxt.DynlinkingGo() || ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE) {
-               // No trampolines needed since r2 contains the TOC
-               return
-       }
-
-       t := ld.Symaddr(r.Sym) + r.Add - (s.Value + int64(r.Off))
-       switch r.Type {
-       case objabi.R_CALLPOWER:
-
-               // If branch offset is too far then create a trampoline.
-
-               if (ctxt.LinkMode == ld.LinkExternal && s.Sect != r.Sym.Sect) || (ctxt.LinkMode == ld.LinkInternal && int64(int32(t<<6)>>6) != t) || (*ld.FlagDebugTramp > 1 && s.File != r.Sym.File) {
-                       var tramp *sym.Symbol
-                       for i := 0; ; i++ {
-
-                               // Using r.Add as part of the name is significant in functions like duffzero where the call
-                               // target is at some offset within the function.  Calls to duff+8 and duff+256 must appear as
-                               // distinct trampolines.
-
-                               name := r.Sym.Name
-                               if r.Add == 0 {
-                                       name = name + fmt.Sprintf("-tramp%d", i)
-                               } else {
-                                       name = name + fmt.Sprintf("%+x-tramp%d", r.Add, i)
-                               }
-
-                               // Look up the trampoline in case it already exists
-
-                               tramp = ctxt.Syms.Lookup(name, int(r.Sym.Version))
-                               if tramp.Value == 0 {
-                                       break
-                               }
-
-                               t = ld.Symaddr(tramp) + r.Add - (s.Value + int64(r.Off))
-
-                               // With internal linking, the trampoline can be used if it is not too far.
-                               // With external linking, the trampoline must be in this section for it to be reused.
-                               if (ctxt.LinkMode == ld.LinkInternal && int64(int32(t<<6)>>6) == t) || (ctxt.LinkMode == ld.LinkExternal && s.Sect == tramp.Sect) {
-                                       break
-                               }
-                       }
-                       if tramp.Type == 0 {
-                               if ctxt.DynlinkingGo() || ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE {
-                                       // Should have returned for above cases
-                                       ld.Errorf(s, "unexpected trampoline for shared or dynamic linking\n")
-                               } else {
-                                       ctxt.AddTramp(tramp)
-                                       gentramp(ctxt, tramp, r.Sym, r.Add)
-                               }
-                       }
-                       r.Sym = tramp
-                       r.Add = 0 // This was folded into the trampoline target address
-                       r.Done = false
-               }
-       default:
-               ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
-       }
-}
-
-func gentramp(ctxt *ld.Link, tramp, target *sym.Symbol, offset int64) {
-       tramp.Size = 16 // 4 instructions
-       tramp.P = make([]byte, tramp.Size)
-       t := ld.Symaddr(target) + offset
-       var o1, o2 uint32
-
-       if ctxt.HeadType == objabi.Haix {
-               // On AIX, the address is retrieved with a TOC symbol.
-               // For internal linking, the "Linux" way might still be used.
-               // However, all text symbols are accessed with a TOC symbol as
-               // text relocations aren't supposed to be possible.
-               // So, keep using the external linking way to be more AIX friendly.
-               o1 = uint32(0x3fe20000) // lis r2, toctargetaddr hi
-               o2 = uint32(0xebff0000) // ld r31, toctargetaddr lo
-
-               toctramp := ctxt.Syms.Lookup("TOC."+tramp.Name, 0)
-               toctramp.Type = sym.SXCOFFTOC
-               toctramp.Attr |= sym.AttrReachable
-               toctramp.AddAddr(ctxt.Arch, target)
-
-               tr := tramp.AddRel()
-               tr.Off = 0
-               tr.Type = objabi.R_ADDRPOWER_TOCREL_DS
-               tr.Siz = 8 // generates 2 relocations:  HA + LO
-               tr.Sym = toctramp
-               tr.Add = offset
-       } else {
-               // Used for default build mode for an executable
-               // Address of the call target is generated using
-               // relocation and doesn't depend on r2 (TOC).
-               o1 = uint32(0x3fe00000) // lis r31,targetaddr hi
-               o2 = uint32(0x3bff0000) // addi r31,targetaddr lo
-
-               // With external linking, the target address must be
-               // relocated using LO and HA
-               if ctxt.LinkMode == ld.LinkExternal {
-                       tr := tramp.AddRel()
-                       tr.Off = 0
-                       tr.Type = objabi.R_ADDRPOWER
-                       tr.Siz = 8 // generates 2 relocations:  HA + LO
-                       tr.Sym = target
-                       tr.Add = offset
-
-               } else {
-                       // adjustment needed if lo has sign bit set
-                       // when using addi to compute address
-                       val := uint32((t & 0xffff0000) >> 16)
-                       if t&0x8000 != 0 {
-                               val += 1
-                       }
-                       o1 |= val                // hi part of addr
-                       o2 |= uint32(t & 0xffff) // lo part of addr
-               }
-       }
-
-       o3 := uint32(0x7fe903a6) // mtctr r31
-       o4 := uint32(0x4e800420) // bctr
-       ctxt.Arch.ByteOrder.PutUint32(tramp.P, o1)
-       ctxt.Arch.ByteOrder.PutUint32(tramp.P[4:], o2)
-       ctxt.Arch.ByteOrder.PutUint32(tramp.P[8:], o3)
-       ctxt.Arch.ByteOrder.PutUint32(tramp.P[12:], o4)
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-       if ctxt.LinkMode == ld.LinkExternal {
-               // On AIX, relocations (except TLS ones) must be also done to the
-               // value with the current addresses.
-               switch r.Type {
-               default:
-                       if ctxt.HeadType != objabi.Haix {
-                               return val, false
-                       }
-               case objabi.R_POWER_TLS, objabi.R_POWER_TLS_LE, objabi.R_POWER_TLS_IE:
-                       r.Done = false
-                       // check Outer is nil, Type is TLSBSS?
-                       r.Xadd = r.Add
-                       r.Xsym = r.Sym
-                       return val, true
-               case objabi.R_ADDRPOWER,
-                       objabi.R_ADDRPOWER_DS,
-                       objabi.R_ADDRPOWER_TOCREL,
-                       objabi.R_ADDRPOWER_TOCREL_DS,
-                       objabi.R_ADDRPOWER_GOT,
-                       objabi.R_ADDRPOWER_PCREL:
-                       r.Done = false
-
-                       // set up addend for eventual relocation via outer symbol.
-                       rs := r.Sym
-                       r.Xadd = r.Add
-                       for rs.Outer != nil {
-                               r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
-                               rs = rs.Outer
-                       }
-
-                       if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Type != sym.SUNDEFEXT && rs.Sect == nil {
-                               ld.Errorf(s, "missing section for %s", rs.Name)
-                       }
-                       r.Xsym = rs
-
-                       if ctxt.HeadType != objabi.Haix {
-                               return val, true
-                       }
-               case objabi.R_CALLPOWER:
-                       r.Done = false
-                       r.Xsym = r.Sym
-                       r.Xadd = r.Add
-                       if ctxt.HeadType != objabi.Haix {
-                               return val, true
-                       }
-               }
-       }
-
-       switch r.Type {
-       case objabi.R_CONST:
-               return r.Add, true
-       case objabi.R_GOTOFF:
-               return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
-       case objabi.R_ADDRPOWER_TOCREL, objabi.R_ADDRPOWER_TOCREL_DS:
-               return archreloctoc(ctxt, r, s, val), true
-       case objabi.R_ADDRPOWER, objabi.R_ADDRPOWER_DS:
-               return archrelocaddr(ctxt, r, s, val), true
-       case objabi.R_CALLPOWER:
-               // Bits 6 through 29 = (S + A - P) >> 2
-
-               t := ld.Symaddr(r.Sym) + r.Add - (s.Value + int64(r.Off))
-
-               if t&3 != 0 {
-                       ld.Errorf(s, "relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
-               }
-               // If branch offset is too far then create a trampoline.
-
-               if int64(int32(t<<6)>>6) != t {
-                       ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
-               }
-               return val | int64(uint32(t)&^0xfc000003), true
-       case objabi.R_POWER_TOC: // S + A - .TOC.
-               return ld.Symaddr(r.Sym) + r.Add - symtoc(ctxt, s), true
-
-       case objabi.R_POWER_TLS_LE:
-               // The thread pointer points 0x7000 bytes after the start of the
-               // thread local storage area as documented in section "3.7.2 TLS
-               // Runtime Handling" of "Power Architecture 64-Bit ELF V2 ABI
-               // Specification".
-               v := r.Sym.Value - 0x7000
-               if ctxt.HeadType == objabi.Haix {
-                       // On AIX, the thread pointer points 0x7800 bytes after
-                       // the TLS.
-                       v -= 0x800
-               }
-               if int64(int16(v)) != v {
-                       ld.Errorf(s, "TLS offset out of range %d", v)
-               }
-               return (val &^ 0xffff) | (v & 0xffff), true
-       }
-
-       return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-       switch r.Variant & sym.RV_TYPE_MASK {
-       default:
-               ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
-               fallthrough
-
-       case sym.RV_NONE:
-               return t
-
-       case sym.RV_POWER_LO:
-               if r.Variant&sym.RV_CHECK_OVERFLOW != 0 {
-                       // Whether to check for signed or unsigned
-                       // overflow depends on the instruction
-                       var o1 uint32
-                       if ctxt.Arch.ByteOrder == binary.BigEndian {
-                               o1 = binary.BigEndian.Uint32(s.P[r.Off-2:])
-                       } else {
-                               o1 = binary.LittleEndian.Uint32(s.P[r.Off:])
-                       }
-                       switch o1 >> 26 {
-                       case 24, // ori
-                               26, // xori
-                               28: // andi
-                               if t>>16 != 0 {
-                                       goto overflow
-                               }
-
-                       default:
-                               if int64(int16(t)) != t {
-                                       goto overflow
-                               }
-                       }
-               }
-
-               return int64(int16(t))
-
-       case sym.RV_POWER_HA:
-               t += 0x8000
-               fallthrough
-
-               // Fallthrough
-       case sym.RV_POWER_HI:
-               t >>= 16
-
-               if r.Variant&sym.RV_CHECK_OVERFLOW != 0 {
-                       // Whether to check for signed or unsigned
-                       // overflow depends on the instruction
-                       var o1 uint32
-                       if ctxt.Arch.ByteOrder == binary.BigEndian {
-                               o1 = binary.BigEndian.Uint32(s.P[r.Off-2:])
-                       } else {
-                               o1 = binary.LittleEndian.Uint32(s.P[r.Off:])
-                       }
-                       switch o1 >> 26 {
-                       case 25, // oris
-                               27, // xoris
-                               29: // andis
-                               if t>>16 != 0 {
-                                       goto overflow
-                               }
-
-                       default:
-                               if int64(int16(t)) != t {
-                                       goto overflow
-                               }
-                       }
-               }
-
-               return int64(int16(t))
-
-       case sym.RV_POWER_DS:
-               var o1 uint32
-               if ctxt.Arch.ByteOrder == binary.BigEndian {
-                       o1 = uint32(binary.BigEndian.Uint16(s.P[r.Off:]))
-               } else {
-                       o1 = uint32(binary.LittleEndian.Uint16(s.P[r.Off:]))
-               }
-               if t&3 != 0 {
-                       ld.Errorf(s, "relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
-               }
-               if (r.Variant&sym.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t {
-                       goto overflow
-               }
-               return int64(o1)&0x3 | int64(int16(t))
-       }
-
-overflow:
-       ld.Errorf(s, "relocation for %s+%d is too big: %d", r.Sym.Name, r.Off, t)
-       return t
-}
-
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
-       if s.Plt() >= 0 {
-               return
-       }
-
-       ld.Adddynsym(ctxt, s)
-
-       if ctxt.IsELF {
-               plt := ctxt.Syms.Lookup(".plt", 0)
-               rela := ctxt.Syms.Lookup(".rela.plt", 0)
-               if plt.Size == 0 {
-                       elfsetupplt(ctxt)
-               }
-
-               // Create the glink resolver if necessary
-               glink := ensureglinkresolver(ctxt)
-
-               // Write symbol resolver stub (just a branch to the
-               // glink resolver stub)
-               r := glink.AddRel()
-
-               r.Sym = glink
-               r.Off = int32(glink.Size)
-               r.Siz = 4
-               r.Type = objabi.R_CALLPOWER
-               glink.AddUint32(ctxt.Arch, 0x48000000) // b .glink
-
-               // In the ppc64 ABI, the dynamic linker is responsible
-               // for writing the entire PLT.  We just need to
-               // reserve 8 bytes for each PLT entry and generate a
-               // JMP_SLOT dynamic relocation for it.
-               //
-               // TODO(austin): ABI v1 is different
-               s.SetPlt(int32(plt.Size))
-
-               plt.Size += 8
-
-               rela.AddAddrPlus(ctxt.Arch, plt, int64(s.Plt()))
-               rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_PPC64_JMP_SLOT)))
-               rela.AddUint64(ctxt.Arch, 0)
-       } else {
-               ld.Errorf(s, "addpltsym: unsupported binary format")
-       }
-}
-
-// Generate the glink resolver stub if necessary and return the .glink section
-func ensureglinkresolver(ctxt *ld.Link) *sym.Symbol {
-       glink := ctxt.Syms.Lookup(".glink", 0)
-       if glink.Size != 0 {
-               return glink
-       }
-
-       // This is essentially the resolver from the ppc64 ELF ABI.
-       // At entry, r12 holds the address of the symbol resolver stub
-       // for the target routine and the argument registers hold the
-       // arguments for the target routine.
-       //
-       // This stub is PIC, so first get the PC of label 1 into r11.
-       // Other things will be relative to this.
-       glink.AddUint32(ctxt.Arch, 0x7c0802a6) // mflr r0
-       glink.AddUint32(ctxt.Arch, 0x429f0005) // bcl 20,31,1f
-       glink.AddUint32(ctxt.Arch, 0x7d6802a6) // 1: mflr r11
-       glink.AddUint32(ctxt.Arch, 0x7c0803a6) // mtlf r0
-
-       // Compute the .plt array index from the entry point address.
-       // Because this is PIC, everything is relative to label 1b (in
-       // r11):
-       //   r0 = ((r12 - r11) - (res_0 - r11)) / 4 = (r12 - res_0) / 4
-       glink.AddUint32(ctxt.Arch, 0x3800ffd0) // li r0,-(res_0-1b)=-48
-       glink.AddUint32(ctxt.Arch, 0x7c006214) // add r0,r0,r12
-       glink.AddUint32(ctxt.Arch, 0x7c0b0050) // sub r0,r0,r11
-       glink.AddUint32(ctxt.Arch, 0x7800f082) // srdi r0,r0,2
-
-       // r11 = address of the first byte of the PLT
-       r := glink.AddRel()
-
-       r.Off = int32(glink.Size)
-       r.Sym = ctxt.Syms.Lookup(".plt", 0)
-       r.Siz = 8
-       r.Type = objabi.R_ADDRPOWER
-
-       glink.AddUint32(ctxt.Arch, 0x3d600000) // addis r11,0,.plt@ha
-       glink.AddUint32(ctxt.Arch, 0x396b0000) // addi r11,r11,.plt@l
-
-       // Load r12 = dynamic resolver address and r11 = DSO
-       // identifier from the first two doublewords of the PLT.
-       glink.AddUint32(ctxt.Arch, 0xe98b0000) // ld r12,0(r11)
-       glink.AddUint32(ctxt.Arch, 0xe96b0008) // ld r11,8(r11)
-
-       // Jump to the dynamic resolver
-       glink.AddUint32(ctxt.Arch, 0x7d8903a6) // mtctr r12
-       glink.AddUint32(ctxt.Arch, 0x4e800420) // bctr
-
-       // The symbol resolvers must immediately follow.
-       //   res_0:
-
-       // Add DT_PPC64_GLINK .dynamic entry, which points to 32 bytes
-       // before the first symbol resolver stub.
-       s := ctxt.Syms.Lookup(".dynamic", 0)
-
-       ld.Elfwritedynentsymplus(ctxt, s, ld.DT_PPC64_GLINK, glink, glink.Size-32)
-
-       return glink
-}
-
-func asmb(ctxt *ld.Link) {
-       if ctxt.IsELF {
-               ld.Asmbelfsetup()
-       }
-
-       for _, sect := range ld.Segtext.Sections {
-               ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-               // Handle additional text sections with Codeblk
-               if sect.Name == ".text" {
-                       ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-               } else {
-                       ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-               }
-       }
-
-       if ld.Segrodata.Filelen > 0 {
-               ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-               ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-       }
-       if ld.Segrelrodata.Filelen > 0 {
-               ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
-               ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
-       }
-
-       ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-       ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-       ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-       ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-       /* output symbol table */
-       ld.Symsize = 0
-
-       ld.Lcsize = 0
-       symo := uint32(0)
-       if !*ld.FlagS {
-               // TODO: rationalize
-               switch ctxt.HeadType {
-               default:
-                       if ctxt.IsELF {
-                               symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-                               symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
-                       }
-
-               case objabi.Hplan9:
-                       symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
-
-               case objabi.Haix:
-                       // Nothing to do
-               }
-
-               ctxt.Out.SeekSet(int64(symo))
-               switch ctxt.HeadType {
-               default:
-                       if ctxt.IsELF {
-                               ld.Asmelfsym(ctxt)
-                               ctxt.Out.Flush()
-                               ctxt.Out.Write(ld.Elfstrdat)
-
-                               if ctxt.LinkMode == ld.LinkExternal {
-                                       ld.Elfemitreloc(ctxt)
-                               }
-                       }
-
-               case objabi.Hplan9:
-                       ld.Asmplan9sym(ctxt)
-                       ctxt.Out.Flush()
-
-                       sym := ctxt.Syms.Lookup("pclntab", 0)
-                       if sym != nil {
-                               ld.Lcsize = int32(len(sym.P))
-                               ctxt.Out.Write(sym.P)
-                               ctxt.Out.Flush()
-                       }
-
-               case objabi.Haix:
-                       // symtab must be added once sections have been created in ld.Asmbxcoff
-                       ctxt.Out.Flush()
-               }
-       }
-
-       ctxt.Out.SeekSet(0)
-       switch ctxt.HeadType {
-       default:
-       case objabi.Hplan9: /* plan 9 */
-               ctxt.Out.Write32(0x647)                      /* magic */
-               ctxt.Out.Write32(uint32(ld.Segtext.Filelen)) /* sizes */
-               ctxt.Out.Write32(uint32(ld.Segdata.Filelen))
-               ctxt.Out.Write32(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-               ctxt.Out.Write32(uint32(ld.Symsize))          /* nsyms */
-               ctxt.Out.Write32(uint32(ld.Entryvalue(ctxt))) /* va of entry */
-               ctxt.Out.Write32(0)
-               ctxt.Out.Write32(uint32(ld.Lcsize))
-
-       case objabi.Hlinux,
-               objabi.Hfreebsd,
-               objabi.Hnetbsd,
-               objabi.Hopenbsd:
-               ld.Asmbelf(ctxt, int64(symo))
-
-       case objabi.Haix:
-               fileoff := uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-               fileoff = uint32(ld.Rnd(int64(fileoff), int64(*ld.FlagRound)))
-               ld.Asmbxcoff(ctxt, int64(fileoff))
-       }
-
-       ctxt.Out.Flush()
-       if *ld.FlagC {
-               fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
-               fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
-               fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
-               fmt.Printf("symsize=%d\n", ld.Symsize)
-               fmt.Printf("lcsize=%d\n", ld.Lcsize)
-               fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
-       }
-}
diff --git a/src/cmd/oldlink/internal/ppc64/l.go b/src/cmd/oldlink/internal/ppc64/l.go
deleted file mode 100644 (file)
index c78535b..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ppc64
-
-// Writing object files.
-
-// cmd/9l/l.h from Vita Nuova.
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-const (
-       maxAlign  = 32 // max data alignment
-       minAlign  = 1  // min data alignment
-       funcAlign = 16
-)
-
-/* Used by ../internal/ld/dwarf.go */
-const (
-       dwarfRegSP = 1
-       dwarfRegLR = 65
-)
diff --git a/src/cmd/oldlink/internal/ppc64/obj.go b/src/cmd/oldlink/internal/ppc64/obj.go
deleted file mode 100644 (file)
index e9da5a3..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-// Inferno utils/5l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/obj.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package ppc64
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-       arch := sys.ArchPPC64
-       if objabi.GOARCH == "ppc64le" {
-               arch = sys.ArchPPC64LE
-       }
-
-       theArch := ld.Arch{
-               Funcalign:  funcAlign,
-               Maxalign:   maxAlign,
-               Minalign:   minAlign,
-               Dwarfregsp: dwarfRegSP,
-               Dwarfreglr: dwarfRegLR,
-
-               Adddynrel:        adddynrel,
-               Archinit:         archinit,
-               Archreloc:        archreloc,
-               Archrelocvariant: archrelocvariant,
-               Asmb:             asmb,
-               Asmb2:            asmb2,
-               Elfreloc1:        elfreloc1,
-               Elfsetupplt:      elfsetupplt,
-               Gentext:          gentext,
-               Trampoline:       trampoline,
-               Machoreloc1:      machoreloc1,
-               Xcoffreloc1:      xcoffreloc1,
-
-               // TODO(austin): ABI v1 uses /usr/lib/ld.so.1,
-               Linuxdynld: "/lib64/ld64.so.1",
-
-               Freebsddynld:   "XXX",
-               Openbsddynld:   "XXX",
-               Netbsddynld:    "XXX",
-               Dragonflydynld: "XXX",
-               Solarisdynld:   "XXX",
-       }
-
-       return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-       switch ctxt.HeadType {
-       default:
-               ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-
-       case objabi.Hplan9: /* plan 9 */
-               ld.HEADR = 32
-
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = 4128
-               }
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 4096
-               }
-
-       case objabi.Hlinux: /* ppc64 elf */
-               ld.Elfinit(ctxt)
-               ld.HEADR = ld.ELFRESERVE
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
-               }
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 0x10000
-               }
-
-       case objabi.Haix:
-               ld.Xcoffinit(ctxt)
-       }
-}
diff --git a/src/cmd/oldlink/internal/riscv64/asm.go b/src/cmd/oldlink/internal/riscv64/asm.go
deleted file mode 100644 (file)
index f4db32d..0000000
+++ /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 (file)
index a302657..0000000
+++ /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 (file)
index a6a5adb..0000000
+++ /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 (file)
index 6c5744d..0000000
+++ /dev/null
@@ -1,574 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package s390x
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/ld"
-       "cmd/oldlink/internal/sym"
-       "debug/elf"
-       "fmt"
-)
-
-// gentext generates assembly to append the local moduledata to the global
-// moduledata linked list at initialization time. This is only done if the runtime
-// is in a different module.
-//
-// <go.link.addmoduledata>:
-//     larl  %r2, <local.moduledata>
-//     jg    <runtime.addmoduledata@plt>
-//     undef
-//
-// The job of appending the moduledata is delegated to runtime.addmoduledata.
-func gentext(ctxt *ld.Link) {
-       if !ctxt.DynlinkingGo() {
-               return
-       }
-       addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-       if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
-               // we're linking a module containing the runtime -> no need for
-               // an init function
-               return
-       }
-       addmoduledata.Attr |= sym.AttrReachable
-       initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-       initfunc.Type = sym.STEXT
-       initfunc.Attr |= sym.AttrLocal
-       initfunc.Attr |= sym.AttrReachable
-
-       // larl %r2, <local.moduledata>
-       initfunc.AddUint8(0xc0)
-       initfunc.AddUint8(0x20)
-       lmd := initfunc.AddRel()
-       lmd.InitExt()
-       lmd.Off = int32(initfunc.Size)
-       lmd.Siz = 4
-       lmd.Sym = ctxt.Moduledata
-       lmd.Type = objabi.R_PCREL
-       lmd.Variant = sym.RV_390_DBL
-       lmd.Add = 2 + int64(lmd.Siz)
-       initfunc.AddUint32(ctxt.Arch, 0)
-
-       // jg <runtime.addmoduledata[@plt]>
-       initfunc.AddUint8(0xc0)
-       initfunc.AddUint8(0xf4)
-       rel := initfunc.AddRel()
-       rel.InitExt()
-       rel.Off = int32(initfunc.Size)
-       rel.Siz = 4
-       rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-       rel.Type = objabi.R_CALL
-       rel.Variant = sym.RV_390_DBL
-       rel.Add = 2 + int64(rel.Siz)
-       initfunc.AddUint32(ctxt.Arch, 0)
-
-       // undef (for debugging)
-       initfunc.AddUint32(ctxt.Arch, 0)
-       if ctxt.BuildMode == ld.BuildModePlugin {
-               ctxt.Textp = append(ctxt.Textp, addmoduledata)
-       }
-       ctxt.Textp = append(ctxt.Textp, initfunc)
-       initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-       initarray_entry.Attr |= sym.AttrLocal
-       initarray_entry.Attr |= sym.AttrReachable
-       initarray_entry.Type = sym.SINITARR
-       initarray_entry.AddAddr(ctxt.Arch, initfunc)
-}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-       targ := r.Sym
-       r.InitExt()
-
-       switch r.Type {
-       default:
-               if r.Type >= objabi.ElfRelocOffset {
-                       ld.Errorf(s, "unexpected relocation type %d", r.Type)
-                       return false
-               }
-
-               // Handle relocations found in ELF object files.
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_12),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOT12):
-               ld.Errorf(s, "s390x 12-bit relocations have not been implemented (relocation type %d)", r.Type-objabi.ElfRelocOffset)
-               return false
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_8),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_16),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_32),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_64):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected R_390_nn relocation for dynamic symbol %s", targ.Name)
-               }
-               r.Type = objabi.R_ADDR
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC16),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC32),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC64):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected R_390_PCnn relocation for dynamic symbol %s", targ.Name)
-               }
-               // TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
-               // sense and should be removed when someone has thought about it properly.
-               if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
-                       ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
-               }
-               r.Type = objabi.R_PCREL
-               r.Add += int64(r.Siz)
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOT16),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOT32),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOT64):
-               ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-objabi.ElfRelocOffset)
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PLT16DBL),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PLT32DBL):
-               r.Type = objabi.R_PCREL
-               r.Variant = sym.RV_390_DBL
-               r.Add += int64(r.Siz)
-               if targ.Type == sym.SDYNIMPORT {
-                       addpltsym(ctxt, targ)
-                       r.Sym = ctxt.Syms.Lookup(".plt", 0)
-                       r.Add += int64(targ.Plt())
-               }
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PLT32),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PLT64):
-               r.Type = objabi.R_PCREL
-               r.Add += int64(r.Siz)
-               if targ.Type == sym.SDYNIMPORT {
-                       addpltsym(ctxt, targ)
-                       r.Sym = ctxt.Syms.Lookup(".plt", 0)
-                       r.Add += int64(targ.Plt())
-               }
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_COPY):
-               ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-objabi.ElfRelocOffset)
-               return false
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GLOB_DAT):
-               ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-objabi.ElfRelocOffset)
-               return false
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_JMP_SLOT):
-               ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-objabi.ElfRelocOffset)
-               return false
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_RELATIVE):
-               ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-objabi.ElfRelocOffset)
-               return false
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTOFF):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected R_390_GOTOFF relocation for dynamic symbol %s", targ.Name)
-               }
-               r.Type = objabi.R_GOTOFF
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTPC):
-               r.Type = objabi.R_PCREL
-               r.Sym = ctxt.Syms.Lookup(".got", 0)
-               r.Add += int64(r.Siz)
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC16DBL),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC32DBL):
-               r.Type = objabi.R_PCREL
-               r.Variant = sym.RV_390_DBL
-               r.Add += int64(r.Siz)
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected R_390_PCnnDBL relocation for dynamic symbol %s", targ.Name)
-               }
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTPCDBL):
-               r.Type = objabi.R_PCREL
-               r.Variant = sym.RV_390_DBL
-               r.Sym = ctxt.Syms.Lookup(".got", 0)
-               r.Add += int64(r.Siz)
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTENT):
-               addgotsym(ctxt, targ)
-
-               r.Type = objabi.R_PCREL
-               r.Variant = sym.RV_390_DBL
-               r.Sym = ctxt.Syms.Lookup(".got", 0)
-               r.Add += int64(targ.Got())
-               r.Add += int64(r.Siz)
-               return true
-       }
-       // Handle references to ELF symbols from our own object files.
-       if targ.Type != sym.SDYNIMPORT {
-               return true
-       }
-
-       return false
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-       ctxt.Out.Write64(uint64(sectoff))
-
-       elfsym := r.Xsym.ElfsymForReloc()
-       switch r.Type {
-       default:
-               return false
-       case objabi.R_TLS_LE:
-               switch r.Siz {
-               default:
-                       return false
-               case 4:
-                       // WARNING - silently ignored by linker in ELF64
-                       ctxt.Out.Write64(uint64(elf.R_390_TLS_LE32) | uint64(elfsym)<<32)
-               case 8:
-                       // WARNING - silently ignored by linker in ELF32
-                       ctxt.Out.Write64(uint64(elf.R_390_TLS_LE64) | uint64(elfsym)<<32)
-               }
-       case objabi.R_TLS_IE:
-               switch r.Siz {
-               default:
-                       return false
-               case 4:
-                       ctxt.Out.Write64(uint64(elf.R_390_TLS_IEENT) | uint64(elfsym)<<32)
-               }
-       case objabi.R_ADDR:
-               switch r.Siz {
-               default:
-                       return false
-               case 4:
-                       ctxt.Out.Write64(uint64(elf.R_390_32) | uint64(elfsym)<<32)
-               case 8:
-                       ctxt.Out.Write64(uint64(elf.R_390_64) | uint64(elfsym)<<32)
-               }
-       case objabi.R_GOTPCREL:
-               if r.Siz == 4 {
-                       ctxt.Out.Write64(uint64(elf.R_390_GOTENT) | uint64(elfsym)<<32)
-               } else {
-                       return false
-               }
-       case objabi.R_PCREL, objabi.R_PCRELDBL, objabi.R_CALL:
-               elfrel := elf.R_390_NONE
-               isdbl := r.Variant&sym.RV_TYPE_MASK == sym.RV_390_DBL
-               // TODO(mundaym): all DBL style relocations should be
-               // signalled using the variant - see issue 14218.
-               switch r.Type {
-               case objabi.R_PCRELDBL, objabi.R_CALL:
-                       isdbl = true
-               }
-               if r.Xsym.Type == sym.SDYNIMPORT && (r.Xsym.ElfType() == elf.STT_FUNC || r.Type == objabi.R_CALL) {
-                       if isdbl {
-                               switch r.Siz {
-                               case 2:
-                                       elfrel = elf.R_390_PLT16DBL
-                               case 4:
-                                       elfrel = elf.R_390_PLT32DBL
-                               }
-                       } else {
-                               switch r.Siz {
-                               case 4:
-                                       elfrel = elf.R_390_PLT32
-                               case 8:
-                                       elfrel = elf.R_390_PLT64
-                               }
-                       }
-               } else {
-                       if isdbl {
-                               switch r.Siz {
-                               case 2:
-                                       elfrel = elf.R_390_PC16DBL
-                               case 4:
-                                       elfrel = elf.R_390_PC32DBL
-                               }
-                       } else {
-                               switch r.Siz {
-                               case 2:
-                                       elfrel = elf.R_390_PC16
-                               case 4:
-                                       elfrel = elf.R_390_PC32
-                               case 8:
-                                       elfrel = elf.R_390_PC64
-                               }
-                       }
-               }
-               if elfrel == elf.R_390_NONE {
-                       return false // unsupported size/dbl combination
-               }
-               ctxt.Out.Write64(uint64(elfrel) | uint64(elfsym)<<32)
-       }
-
-       ctxt.Out.Write64(uint64(r.Xadd))
-       return true
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-       plt := ctxt.Syms.Lookup(".plt", 0)
-       got := ctxt.Syms.Lookup(".got", 0)
-       if plt.Size == 0 {
-               // stg     %r1,56(%r15)
-               plt.AddUint8(0xe3)
-               plt.AddUint8(0x10)
-               plt.AddUint8(0xf0)
-               plt.AddUint8(0x38)
-               plt.AddUint8(0x00)
-               plt.AddUint8(0x24)
-               // larl    %r1,_GLOBAL_OFFSET_TABLE_
-               plt.AddUint8(0xc0)
-               plt.AddUint8(0x10)
-               plt.AddPCRelPlus(ctxt.Arch, got, 6)
-               // mvc     48(8,%r15),8(%r1)
-               plt.AddUint8(0xd2)
-               plt.AddUint8(0x07)
-               plt.AddUint8(0xf0)
-               plt.AddUint8(0x30)
-               plt.AddUint8(0x10)
-               plt.AddUint8(0x08)
-               // lg      %r1,16(%r1)
-               plt.AddUint8(0xe3)
-               plt.AddUint8(0x10)
-               plt.AddUint8(0x10)
-               plt.AddUint8(0x10)
-               plt.AddUint8(0x00)
-               plt.AddUint8(0x04)
-               // br      %r1
-               plt.AddUint8(0x07)
-               plt.AddUint8(0xf1)
-               // nopr    %r0
-               plt.AddUint8(0x07)
-               plt.AddUint8(0x00)
-               // nopr    %r0
-               plt.AddUint8(0x07)
-               plt.AddUint8(0x00)
-               // nopr    %r0
-               plt.AddUint8(0x07)
-               plt.AddUint8(0x00)
-
-               // assume got->size == 0 too
-               got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
-
-               got.AddUint64(ctxt.Arch, 0)
-               got.AddUint64(ctxt.Arch, 0)
-       }
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-       return false
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-       if ctxt.LinkMode == ld.LinkExternal {
-               return val, false
-       }
-
-       switch r.Type {
-       case objabi.R_CONST:
-               return r.Add, true
-       case objabi.R_GOTOFF:
-               return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
-       }
-
-       return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-       switch r.Variant & sym.RV_TYPE_MASK {
-       default:
-               ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
-               return t
-
-       case sym.RV_NONE:
-               return t
-
-       case sym.RV_390_DBL:
-               if (t & 1) != 0 {
-                       ld.Errorf(s, "%s+%v is not 2-byte aligned", r.Sym.Name, r.Sym.Value)
-               }
-               return t >> 1
-       }
-}
-
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
-       if s.Plt() >= 0 {
-               return
-       }
-
-       ld.Adddynsym(ctxt, s)
-
-       if ctxt.IsELF {
-               plt := ctxt.Syms.Lookup(".plt", 0)
-               got := ctxt.Syms.Lookup(".got", 0)
-               rela := ctxt.Syms.Lookup(".rela.plt", 0)
-               if plt.Size == 0 {
-                       elfsetupplt(ctxt)
-               }
-               // larl    %r1,_GLOBAL_OFFSET_TABLE_+index
-
-               plt.AddUint8(0xc0)
-               plt.AddUint8(0x10)
-               plt.AddPCRelPlus(ctxt.Arch, got, got.Size+6) // need variant?
-
-               // add to got: pointer to current pos in plt
-               got.AddAddrPlus(ctxt.Arch, plt, plt.Size+8) // weird but correct
-               // lg      %r1,0(%r1)
-               plt.AddUint8(0xe3)
-               plt.AddUint8(0x10)
-               plt.AddUint8(0x10)
-               plt.AddUint8(0x00)
-               plt.AddUint8(0x00)
-               plt.AddUint8(0x04)
-               // br      %r1
-               plt.AddUint8(0x07)
-               plt.AddUint8(0xf1)
-               // basr    %r1,%r0
-               plt.AddUint8(0x0d)
-               plt.AddUint8(0x10)
-               // lgf     %r1,12(%r1)
-               plt.AddUint8(0xe3)
-               plt.AddUint8(0x10)
-               plt.AddUint8(0x10)
-               plt.AddUint8(0x0c)
-               plt.AddUint8(0x00)
-               plt.AddUint8(0x14)
-               // jg .plt
-               plt.AddUint8(0xc0)
-               plt.AddUint8(0xf4)
-
-               plt.AddUint32(ctxt.Arch, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation
-               //.plt index
-               plt.AddUint32(ctxt.Arch, uint32(rela.Size)) // rela size before current entry
-
-               // rela
-               rela.AddAddrPlus(ctxt.Arch, got, got.Size-8)
-
-               rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_JMP_SLOT)))
-               rela.AddUint64(ctxt.Arch, 0)
-
-               s.SetPlt(int32(plt.Size - 32))
-
-       } else {
-               ld.Errorf(s, "addpltsym: unsupported binary format")
-       }
-}
-
-func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
-       if s.Got() >= 0 {
-               return
-       }
-
-       ld.Adddynsym(ctxt, s)
-       got := ctxt.Syms.Lookup(".got", 0)
-       s.SetGot(int32(got.Size))
-       got.AddUint64(ctxt.Arch, 0)
-
-       if ctxt.IsELF {
-               rela := ctxt.Syms.Lookup(".rela", 0)
-               rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
-               rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_GLOB_DAT)))
-               rela.AddUint64(ctxt.Arch, 0)
-       } else {
-               ld.Errorf(s, "addgotsym: unsupported binary format")
-       }
-}
-
-func asmb(ctxt *ld.Link) {
-       if ctxt.IsELF {
-               ld.Asmbelfsetup()
-       }
-
-       sect := ld.Segtext.Sections[0]
-       ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-       ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-       for _, sect = range ld.Segtext.Sections[1:] {
-               ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-               ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-       }
-
-       if ld.Segrodata.Filelen > 0 {
-               ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-               ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-       }
-       if ld.Segrelrodata.Filelen > 0 {
-               ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
-               ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
-       }
-
-       ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-       ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-       ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-       ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-       /* output symbol table */
-       ld.Symsize = 0
-
-       ld.Lcsize = 0
-       symo := uint32(0)
-       if !*ld.FlagS {
-               if !ctxt.IsELF {
-                       ld.Errorf(nil, "unsupported executable format")
-               }
-               symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-               symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
-
-               ctxt.Out.SeekSet(int64(symo))
-               ld.Asmelfsym(ctxt)
-               ctxt.Out.Flush()
-               ctxt.Out.Write(ld.Elfstrdat)
-
-               if ctxt.LinkMode == ld.LinkExternal {
-                       ld.Elfemitreloc(ctxt)
-               }
-       }
-
-       ctxt.Out.SeekSet(0)
-       switch ctxt.HeadType {
-       default:
-               ld.Errorf(nil, "unsupported operating system")
-       case objabi.Hlinux:
-               ld.Asmbelf(ctxt, int64(symo))
-       }
-
-       ctxt.Out.Flush()
-       if *ld.FlagC {
-               fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
-               fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
-               fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
-               fmt.Printf("symsize=%d\n", ld.Symsize)
-               fmt.Printf("lcsize=%d\n", ld.Lcsize)
-               fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
-       }
-}
diff --git a/src/cmd/oldlink/internal/s390x/l.go b/src/cmd/oldlink/internal/s390x/l.go
deleted file mode 100644 (file)
index 87d10ee..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-// Inferno utils/5l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package s390x
-
-// Writing object files.
-
-// cmd/9l/l.h from Vita Nuova.
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-const (
-       maxAlign  = 32 // max data alignment
-       minAlign  = 2  // min data alignment
-       funcAlign = 16
-)
-
-/* Used by ../internal/ld/dwarf.go */
-const (
-       dwarfRegSP = 15
-       dwarfRegLR = 14
-)
diff --git a/src/cmd/oldlink/internal/s390x/obj.go b/src/cmd/oldlink/internal/s390x/obj.go
deleted file mode 100644 (file)
index b4af86b..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-// Inferno utils/5l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/obj.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package s390x
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-       arch := sys.ArchS390X
-
-       theArch := ld.Arch{
-               Funcalign:  funcAlign,
-               Maxalign:   maxAlign,
-               Minalign:   minAlign,
-               Dwarfregsp: dwarfRegSP,
-               Dwarfreglr: dwarfRegLR,
-
-               Adddynrel:        adddynrel,
-               Archinit:         archinit,
-               Archreloc:        archreloc,
-               Archrelocvariant: archrelocvariant,
-               Asmb:             asmb,  // in asm.go
-               Asmb2:            asmb2, // in asm.go
-               Elfreloc1:        elfreloc1,
-               Elfsetupplt:      elfsetupplt,
-               Gentext:          gentext,
-               Machoreloc1:      machoreloc1,
-
-               Linuxdynld: "/lib64/ld64.so.1",
-
-               // not relevant for s390x
-               Freebsddynld:   "XXX",
-               Openbsddynld:   "XXX",
-               Netbsddynld:    "XXX",
-               Dragonflydynld: "XXX",
-               Solarisdynld:   "XXX",
-       }
-
-       return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-       switch ctxt.HeadType {
-       default:
-               ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-
-       case objabi.Hlinux: // s390x ELF
-               ld.Elfinit(ctxt)
-               ld.HEADR = ld.ELFRESERVE
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = 0x10000 + int64(ld.HEADR)
-               }
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 0x10000
-               }
-       }
-}
diff --git a/src/cmd/oldlink/internal/sym/attribute.go b/src/cmd/oldlink/internal/sym/attribute.go
deleted file mode 100644 (file)
index 4b69bf3..0000000
+++ /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 (file)
index 02fb0cf..0000000
+++ /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 (file)
index 4f2023b..0000000
+++ /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 (file)
index 4809db8..0000000
+++ /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 (file)
index d5255bf..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-// Inferno utils/8l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/8l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package sym
-
-// Terrible but standard terminology.
-// A segment describes a block of file to load into memory.
-// A section further describes the pieces of that block for
-// use in debuggers and such.
-
-type Segment struct {
-       Rwx      uint8  // permission as usual unix bits (5 = r-x etc)
-       Vaddr    uint64 // virtual address
-       Length   uint64 // length in memory
-       Fileoff  uint64 // file offset
-       Filelen  uint64 // length on disk
-       Sections []*Section
-}
-
-type Section struct {
-       Rwx     uint8
-       Extnum  int16
-       Align   int32
-       Name    string
-       Vaddr   uint64
-       Length  uint64
-       Seg     *Segment
-       Elfsect interface{} // an *ld.ElfShdr
-       Reloff  uint64
-       Rellen  uint64
-}
diff --git a/src/cmd/oldlink/internal/sym/sizeof_test.go b/src/cmd/oldlink/internal/sym/sizeof_test.go
deleted file mode 100644 (file)
index e6e3916..0000000
+++ /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 (file)
index 2756acd..0000000
+++ /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 (file)
index e772496..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-// Derived from Inferno utils/6l/l.h and related files.
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package sym
-
-type Symbols struct {
-       symbolBatch []Symbol
-
-       // Symbol lookup based on name and indexed by version.
-       hash []map[string]*Symbol
-
-       Allsym []*Symbol
-}
-
-func NewSymbols() *Symbols {
-       hash := make([]map[string]*Symbol, SymVerStatic)
-       // Preallocate about 2mb for hash of non static symbols
-       hash[0] = make(map[string]*Symbol, 100000)
-       // And another 1mb for internal ABI text symbols.
-       hash[SymVerABIInternal] = make(map[string]*Symbol, 50000)
-       return &Symbols{
-               hash:   hash,
-               Allsym: make([]*Symbol, 0, 100000),
-       }
-}
-
-func (syms *Symbols) Newsym(name string, v int) *Symbol {
-       batch := syms.symbolBatch
-       if len(batch) == 0 {
-               batch = make([]Symbol, 1000)
-       }
-       s := &batch[0]
-       syms.symbolBatch = batch[1:]
-
-       s.Dynid = -1
-       s.Name = name
-       s.Version = int16(v)
-       syms.Allsym = append(syms.Allsym, s)
-
-       return s
-}
-
-// Look up the symbol with the given name and version, creating the
-// symbol if it is not found.
-func (syms *Symbols) Lookup(name string, v int) *Symbol {
-       m := syms.hash[v]
-       s := m[name]
-       if s != nil {
-               return s
-       }
-       s = syms.Newsym(name, v)
-       m[name] = s
-       return s
-}
-
-// Look up the symbol with the given name and version, returning nil
-// if it is not found.
-func (syms *Symbols) ROLookup(name string, v int) *Symbol {
-       return syms.hash[v][name]
-}
-
-// Add an existing symbol to the symbol table.
-func (syms *Symbols) Add(s *Symbol) {
-       name := s.Name
-       v := int(s.Version)
-       m := syms.hash[v]
-       if _, ok := m[name]; ok {
-               panic(name + " already added")
-       }
-       m[name] = s
-}
-
-// Allocate a new version (i.e. symbol namespace).
-func (syms *Symbols) IncVersion() int {
-       syms.hash = append(syms.hash, make(map[string]*Symbol))
-       return len(syms.hash) - 1
-}
-
-// Rename renames a symbol.
-func (syms *Symbols) Rename(old, new string, v int, reachparent map[*Symbol]*Symbol) {
-       s := syms.hash[v][old]
-       oldExtName := s.Extname()
-       s.Name = new
-       if oldExtName == old {
-               s.SetExtname(new)
-       }
-       delete(syms.hash[v], old)
-
-       dup := syms.hash[v][new]
-       if dup == nil {
-               syms.hash[v][new] = s
-       } else {
-               if s.Type == 0 {
-                       dup.Attr |= s.Attr
-                       if s.Attr.Reachable() && reachparent != nil {
-                               reachparent[dup] = reachparent[s]
-                       }
-                       *s = *dup
-               } else if dup.Type == 0 {
-                       s.Attr |= dup.Attr
-                       if dup.Attr.Reachable() && reachparent != nil {
-                               reachparent[s] = reachparent[dup]
-                       }
-                       *dup = *s
-                       syms.hash[v][new] = s
-               }
-       }
-}
diff --git a/src/cmd/oldlink/internal/sym/symkind.go b/src/cmd/oldlink/internal/sym/symkind.go
deleted file mode 100644 (file)
index 1933dd7..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-// Derived from Inferno utils/6l/l.h and related files.
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package sym
-
-// A SymKind describes the kind of memory represented by a symbol.
-type SymKind uint8
-
-// Defined SymKind values.
-//
-// TODO(rsc): Give idiomatic Go names.
-//go:generate stringer -type=SymKind
-const (
-       Sxxx SymKind = iota
-       STEXT
-       SELFRXSECT
-
-       // Read-only sections.
-       STYPE
-       SSTRING
-       SGOSTRING
-       SGOFUNC
-       SGCBITS
-       SRODATA
-       SFUNCTAB
-
-       SELFROSECT
-       SMACHOPLT
-
-       // Read-only sections with relocations.
-       //
-       // Types STYPE-SFUNCTAB above are written to the .rodata section by default.
-       // When linking a shared object, some conceptually "read only" types need to
-       // be written to by relocations and putting them in a section called
-       // ".rodata" interacts poorly with the system linkers. The GNU linkers
-       // support this situation by arranging for sections of the name
-       // ".data.rel.ro.XXX" to be mprotected read only by the dynamic linker after
-       // relocations have applied, so when the Go linker is creating a shared
-       // object it checks all objects of the above types and bumps any object that
-       // has a relocation to it to the corresponding type below, which are then
-       // written to sections with appropriate magic names.
-       STYPERELRO
-       SSTRINGRELRO
-       SGOSTRINGRELRO
-       SGOFUNCRELRO
-       SGCBITSRELRO
-       SRODATARELRO
-       SFUNCTABRELRO
-
-       // Part of .data.rel.ro if it exists, otherwise part of .rodata.
-       STYPELINK
-       SITABLINK
-       SSYMTAB
-       SPCLNTAB
-
-       // Writable sections.
-       SFirstWritable
-       SBUILDINFO
-       SELFSECT
-       SMACHO
-       SMACHOGOT
-       SWINDOWS
-       SELFGOT
-       SNOPTRDATA
-       SINITARR
-       SDATA
-       SXCOFFTOC
-       SBSS
-       SNOPTRBSS
-       SLIBFUZZER_EXTRA_COUNTER
-       STLSBSS
-       SXREF
-       SMACHOSYMSTR
-       SMACHOSYMTAB
-       SMACHOINDIRECTPLT
-       SMACHOINDIRECTGOT
-       SFILEPATH
-       SCONST
-       SDYNIMPORT
-       SHOSTOBJ
-       SUNDEFEXT // Undefined symbol for resolution by external linker
-
-       // Sections for debugging information
-       SDWARFSECT
-       SDWARFINFO
-       SDWARFRANGE
-       SDWARFLOC
-       SDWARFLINES
-
-       // ABI aliases (these never appear in the output)
-       SABIALIAS
-)
-
-// AbiSymKindToSymKind maps values read from object files (which are
-// of type cmd/internal/objabi.SymKind) to values of type SymKind.
-var AbiSymKindToSymKind = [...]SymKind{
-       Sxxx,
-       STEXT,
-       SRODATA,
-       SNOPTRDATA,
-       SDATA,
-       SBSS,
-       SNOPTRBSS,
-       STLSBSS,
-       SDWARFINFO,
-       SDWARFRANGE,
-       SDWARFLOC,
-       SDWARFLINES,
-       SABIALIAS,
-       SLIBFUZZER_EXTRA_COUNTER,
-}
-
-// ReadOnly are the symbol kinds that form read-only sections. In some
-// cases, if they will require relocations, they are transformed into
-// rel-ro sections using relROMap.
-var ReadOnly = []SymKind{
-       STYPE,
-       SSTRING,
-       SGOSTRING,
-       SGOFUNC,
-       SGCBITS,
-       SRODATA,
-       SFUNCTAB,
-}
-
-// RelROMap describes the transformation of read-only symbols to rel-ro
-// symbols.
-var RelROMap = map[SymKind]SymKind{
-       STYPE:     STYPERELRO,
-       SSTRING:   SSTRINGRELRO,
-       SGOSTRING: SGOSTRINGRELRO,
-       SGOFUNC:   SGOFUNCRELRO,
-       SGCBITS:   SGCBITSRELRO,
-       SRODATA:   SRODATARELRO,
-       SFUNCTAB:  SFUNCTABRELRO,
-}
-
-// IsData returns true if the type is a data type.
-func (t SymKind) IsData() bool {
-       return t == SDATA || t == SNOPTRDATA || t == SBSS || t == SNOPTRBSS
-}
diff --git a/src/cmd/oldlink/internal/sym/symkind_string.go b/src/cmd/oldlink/internal/sym/symkind_string.go
deleted file mode 100644 (file)
index 97af992..0000000
+++ /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 (file)
index 35bc7b1..0000000
+++ /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 (file)
index fdc9fb7..0000000
+++ /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 (file)
index e8e52f6..0000000
+++ /dev/null
@@ -1,699 +0,0 @@
-// Inferno utils/8l/asm.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/8l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package x86
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/ld"
-       "cmd/oldlink/internal/sym"
-       "debug/elf"
-       "log"
-)
-
-// Append 4 bytes to s and create a R_CALL relocation targeting t to fill them in.
-func addcall(ctxt *ld.Link, s *sym.Symbol, t *sym.Symbol) {
-       s.Attr |= sym.AttrReachable
-       i := s.Size
-       s.Size += 4
-       s.Grow(s.Size)
-       r := s.AddRel()
-       r.Sym = t
-       r.Off = int32(i)
-       r.Type = objabi.R_CALL
-       r.Siz = 4
-}
-
-func gentext(ctxt *ld.Link) {
-       if ctxt.DynlinkingGo() {
-               // We need get_pc_thunk.
-       } else {
-               switch ctxt.BuildMode {
-               case ld.BuildModeCArchive:
-                       if !ctxt.IsELF {
-                               return
-                       }
-               case ld.BuildModePIE, ld.BuildModeCShared, ld.BuildModePlugin:
-                       // We need get_pc_thunk.
-               default:
-                       return
-               }
-       }
-
-       // Generate little thunks that load the PC of the next instruction into a register.
-       thunks := make([]*sym.Symbol, 0, 7+len(ctxt.Textp))
-       for _, r := range [...]struct {
-               name string
-               num  uint8
-       }{
-               {"ax", 0},
-               {"cx", 1},
-               {"dx", 2},
-               {"bx", 3},
-               // sp
-               {"bp", 5},
-               {"si", 6},
-               {"di", 7},
-       } {
-               thunkfunc := ctxt.Syms.Lookup("__x86.get_pc_thunk."+r.name, 0)
-               thunkfunc.Type = sym.STEXT
-               thunkfunc.Attr |= sym.AttrLocal
-               thunkfunc.Attr |= sym.AttrReachable //TODO: remove?
-               o := func(op ...uint8) {
-                       for _, op1 := range op {
-                               thunkfunc.AddUint8(op1)
-                       }
-               }
-               // 8b 04 24     mov    (%esp),%eax
-               // Destination register is in bits 3-5 of the middle byte, so add that in.
-               o(0x8b, 0x04+r.num<<3, 0x24)
-               // c3           ret
-               o(0xc3)
-
-               thunks = append(thunks, thunkfunc)
-       }
-       ctxt.Textp = append(thunks, ctxt.Textp...) // keep Textp in dependency order
-
-       addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
-       if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
-               // we're linking a module containing the runtime -> no need for
-               // an init function
-               return
-       }
-
-       addmoduledata.Attr |= sym.AttrReachable
-
-       initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
-       initfunc.Type = sym.STEXT
-       initfunc.Attr |= sym.AttrLocal
-       initfunc.Attr |= sym.AttrReachable
-       o := func(op ...uint8) {
-               for _, op1 := range op {
-                       initfunc.AddUint8(op1)
-               }
-       }
-
-       // go.link.addmoduledata:
-       //      53                      push %ebx
-       //      e8 00 00 00 00          call __x86.get_pc_thunk.cx + R_CALL __x86.get_pc_thunk.cx
-       //      8d 81 00 00 00 00       lea 0x0(%ecx), %eax + R_PCREL ctxt.Moduledata
-       //      8d 99 00 00 00 00       lea 0x0(%ecx), %ebx + R_GOTPC _GLOBAL_OFFSET_TABLE_
-       //      e8 00 00 00 00          call runtime.addmoduledata@plt + R_CALL runtime.addmoduledata
-       //      5b                      pop %ebx
-       //      c3                      ret
-
-       o(0x53)
-
-       o(0xe8)
-       addcall(ctxt, initfunc, ctxt.Syms.Lookup("__x86.get_pc_thunk.cx", 0))
-
-       o(0x8d, 0x81)
-       initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata, 6)
-
-       o(0x8d, 0x99)
-       i := initfunc.Size
-       initfunc.Size += 4
-       initfunc.Grow(initfunc.Size)
-       r := initfunc.AddRel()
-       r.Sym = ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
-       r.Off = int32(i)
-       r.Type = objabi.R_PCREL
-       r.Add = 12
-       r.Siz = 4
-
-       o(0xe8)
-       addcall(ctxt, initfunc, addmoduledata)
-
-       o(0x5b)
-
-       o(0xc3)
-
-       if ctxt.BuildMode == ld.BuildModePlugin {
-               ctxt.Textp = append(ctxt.Textp, addmoduledata)
-       }
-       ctxt.Textp = append(ctxt.Textp, initfunc)
-       initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
-       initarray_entry.Attr |= sym.AttrReachable
-       initarray_entry.Attr |= sym.AttrLocal
-       initarray_entry.Type = sym.SINITARR
-       initarray_entry.AddAddr(ctxt.Arch, initfunc)
-}
-
-func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
-       targ := r.Sym
-
-       switch r.Type {
-       default:
-               if r.Type >= objabi.ElfRelocOffset {
-                       ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
-                       return false
-               }
-
-               // Handle relocations found in ELF object files.
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_PC32):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected R_386_PC32 relocation for dynamic symbol %s", targ.Name)
-               }
-               // TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
-               // sense and should be removed when someone has thought about it properly.
-               if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
-                       ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
-               }
-               r.Type = objabi.R_PCREL
-               r.Add += 4
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_PLT32):
-               r.Type = objabi.R_PCREL
-               r.Add += 4
-               if targ.Type == sym.SDYNIMPORT {
-                       addpltsym(ctxt, targ)
-                       r.Sym = ctxt.Syms.Lookup(".plt", 0)
-                       r.Add += int64(targ.Plt())
-               }
-
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_GOT32),
-               objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_GOT32X):
-               if targ.Type != sym.SDYNIMPORT {
-                       // have symbol
-                       if r.Off >= 2 && s.P[r.Off-2] == 0x8b {
-                               // turn MOVL of GOT entry into LEAL of symbol address, relative to GOT.
-                               s.P[r.Off-2] = 0x8d
-
-                               r.Type = objabi.R_GOTOFF
-                               return true
-                       }
-
-                       if r.Off >= 2 && s.P[r.Off-2] == 0xff && s.P[r.Off-1] == 0xb3 {
-                               // turn PUSHL of GOT entry into PUSHL of symbol itself.
-                               // use unnecessary SS prefix to keep instruction same length.
-                               s.P[r.Off-2] = 0x36
-
-                               s.P[r.Off-1] = 0x68
-                               r.Type = objabi.R_ADDR
-                               return true
-                       }
-
-                       ld.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
-                       return false
-               }
-
-               addgotsym(ctxt, targ)
-               r.Type = objabi.R_CONST // write r->add during relocsym
-               r.Sym = nil
-               r.Add += int64(targ.Got())
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_GOTOFF):
-               r.Type = objabi.R_GOTOFF
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_GOTPC):
-               r.Type = objabi.R_PCREL
-               r.Sym = ctxt.Syms.Lookup(".got", 0)
-               r.Add += 4
-               return true
-
-       case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_32):
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected R_386_32 relocation for dynamic symbol %s", targ.Name)
-               }
-               r.Type = objabi.R_ADDR
-               return true
-
-       case objabi.MachoRelocOffset + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 0:
-               r.Type = objabi.R_ADDR
-               if targ.Type == sym.SDYNIMPORT {
-                       ld.Errorf(s, "unexpected reloc for dynamic symbol %s", targ.Name)
-               }
-               return true
-
-       case objabi.MachoRelocOffset + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 1:
-               if targ.Type == sym.SDYNIMPORT {
-                       addpltsym(ctxt, targ)
-                       r.Sym = ctxt.Syms.Lookup(".plt", 0)
-                       r.Add = int64(targ.Plt())
-                       r.Type = objabi.R_PCREL
-                       return true
-               }
-
-               r.Type = objabi.R_PCREL
-               return true
-
-       case objabi.MachoRelocOffset + ld.MACHO_FAKE_GOTPCREL:
-               if targ.Type != sym.SDYNIMPORT {
-                       // have symbol
-                       // turn MOVL of GOT entry into LEAL of symbol itself
-                       if r.Off < 2 || s.P[r.Off-2] != 0x8b {
-                               ld.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
-                               return false
-                       }
-
-                       s.P[r.Off-2] = 0x8d
-                       r.Type = objabi.R_PCREL
-                       return true
-               }
-
-               addgotsym(ctxt, targ)
-               r.Sym = ctxt.Syms.Lookup(".got", 0)
-               r.Add += int64(targ.Got())
-               r.Type = objabi.R_PCREL
-               return true
-       }
-
-       // Handle references to ELF symbols from our own object files.
-       if targ.Type != sym.SDYNIMPORT {
-               return true
-       }
-       switch r.Type {
-       case objabi.R_CALL,
-               objabi.R_PCREL:
-               if ctxt.LinkMode == ld.LinkExternal {
-                       // External linker will do this relocation.
-                       return true
-               }
-               addpltsym(ctxt, targ)
-               r.Sym = ctxt.Syms.Lookup(".plt", 0)
-               r.Add = int64(targ.Plt())
-               return true
-
-       case objabi.R_ADDR:
-               if s.Type != sym.SDATA {
-                       break
-               }
-               if ctxt.IsELF {
-                       ld.Adddynsym(ctxt, targ)
-                       rel := ctxt.Syms.Lookup(".rel", 0)
-                       rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
-                       rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_386_32)))
-                       r.Type = objabi.R_CONST // write r->add during relocsym
-                       r.Sym = nil
-                       return true
-               }
-
-               if ctxt.HeadType == objabi.Hdarwin && s.Size == int64(ctxt.Arch.PtrSize) && r.Off == 0 {
-                       // Mach-O relocations are a royal pain to lay out.
-                       // They use a compact stateful bytecode representation
-                       // that is too much bother to deal with.
-                       // Instead, interpret the C declaration
-                       //      void *_Cvar_stderr = &stderr;
-                       // as making _Cvar_stderr the name of a GOT entry
-                       // for stderr. This is separate from the usual GOT entry,
-                       // just in case the C code assigns to the variable,
-                       // and of course it only works for single pointers,
-                       // but we only need to support cgo and that's all it needs.
-                       ld.Adddynsym(ctxt, targ)
-
-                       got := ctxt.Syms.Lookup(".got", 0)
-                       s.Type = got.Type
-                       s.Attr |= sym.AttrSubSymbol
-                       s.Outer = got
-                       s.Sub = got.Sub
-                       got.Sub = s
-                       s.Value = got.Size
-                       got.AddUint32(ctxt.Arch, 0)
-                       ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(targ.Dynid))
-                       r.Type = objabi.ElfRelocOffset // ignore during relocsym
-                       return true
-               }
-       }
-
-       return false
-}
-
-func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
-       ctxt.Out.Write32(uint32(sectoff))
-
-       elfsym := r.Xsym.ElfsymForReloc()
-       switch r.Type {
-       default:
-               return false
-       case objabi.R_ADDR:
-               if r.Siz == 4 {
-                       ctxt.Out.Write32(uint32(elf.R_386_32) | uint32(elfsym)<<8)
-               } else {
-                       return false
-               }
-       case objabi.R_GOTPCREL:
-               if r.Siz == 4 {
-                       ctxt.Out.Write32(uint32(elf.R_386_GOTPC))
-                       if r.Xsym.Name != "_GLOBAL_OFFSET_TABLE_" {
-                               ctxt.Out.Write32(uint32(sectoff))
-                               ctxt.Out.Write32(uint32(elf.R_386_GOT32) | uint32(elfsym)<<8)
-                       }
-               } else {
-                       return false
-               }
-       case objabi.R_CALL:
-               if r.Siz == 4 {
-                       if r.Xsym.Type == sym.SDYNIMPORT {
-                               ctxt.Out.Write32(uint32(elf.R_386_PLT32) | uint32(elfsym)<<8)
-                       } else {
-                               ctxt.Out.Write32(uint32(elf.R_386_PC32) | uint32(elfsym)<<8)
-                       }
-               } else {
-                       return false
-               }
-       case objabi.R_PCREL:
-               if r.Siz == 4 {
-                       ctxt.Out.Write32(uint32(elf.R_386_PC32) | uint32(elfsym)<<8)
-               } else {
-                       return false
-               }
-       case objabi.R_TLS_LE:
-               if r.Siz == 4 {
-                       ctxt.Out.Write32(uint32(elf.R_386_TLS_LE) | uint32(elfsym)<<8)
-               } else {
-                       return false
-               }
-       case objabi.R_TLS_IE:
-               if r.Siz == 4 {
-                       ctxt.Out.Write32(uint32(elf.R_386_GOTPC))
-                       ctxt.Out.Write32(uint32(sectoff))
-                       ctxt.Out.Write32(uint32(elf.R_386_TLS_GOTIE) | uint32(elfsym)<<8)
-               } else {
-                       return false
-               }
-       }
-
-       return true
-}
-
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-       return false
-}
-
-func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
-       var v uint32
-
-       rs := r.Xsym
-
-       if rs.Dynid < 0 {
-               ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
-               return false
-       }
-
-       out.Write32(uint32(sectoff))
-       out.Write32(uint32(rs.Dynid))
-
-       switch r.Type {
-       default:
-               return false
-
-       case objabi.R_DWARFSECREF:
-               v = ld.IMAGE_REL_I386_SECREL
-
-       case objabi.R_ADDR:
-               v = ld.IMAGE_REL_I386_DIR32
-
-       case objabi.R_CALL,
-               objabi.R_PCREL:
-               v = ld.IMAGE_REL_I386_REL32
-       }
-
-       out.Write16(uint16(v))
-
-       return true
-}
-
-func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
-       if ctxt.LinkMode == ld.LinkExternal {
-               return val, false
-       }
-       switch r.Type {
-       case objabi.R_CONST:
-               return r.Add, true
-       case objabi.R_GOTOFF:
-               return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
-       }
-
-       return val, false
-}
-
-func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-       log.Fatalf("unexpected relocation variant")
-       return t
-}
-
-func elfsetupplt(ctxt *ld.Link) {
-       plt := ctxt.Syms.Lookup(".plt", 0)
-       got := ctxt.Syms.Lookup(".got.plt", 0)
-       if plt.Size == 0 {
-               // pushl got+4
-               plt.AddUint8(0xff)
-
-               plt.AddUint8(0x35)
-               plt.AddAddrPlus(ctxt.Arch, got, 4)
-
-               // jmp *got+8
-               plt.AddUint8(0xff)
-
-               plt.AddUint8(0x25)
-               plt.AddAddrPlus(ctxt.Arch, got, 8)
-
-               // zero pad
-               plt.AddUint32(ctxt.Arch, 0)
-
-               // assume got->size == 0 too
-               got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
-
-               got.AddUint32(ctxt.Arch, 0)
-               got.AddUint32(ctxt.Arch, 0)
-       }
-}
-
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
-       if s.Plt() >= 0 {
-               return
-       }
-
-       ld.Adddynsym(ctxt, s)
-
-       if ctxt.IsELF {
-               plt := ctxt.Syms.Lookup(".plt", 0)
-               got := ctxt.Syms.Lookup(".got.plt", 0)
-               rel := ctxt.Syms.Lookup(".rel.plt", 0)
-               if plt.Size == 0 {
-                       elfsetupplt(ctxt)
-               }
-
-               // jmpq *got+size
-               plt.AddUint8(0xff)
-
-               plt.AddUint8(0x25)
-               plt.AddAddrPlus(ctxt.Arch, got, got.Size)
-
-               // add to got: pointer to current pos in plt
-               got.AddAddrPlus(ctxt.Arch, plt, plt.Size)
-
-               // pushl $x
-               plt.AddUint8(0x68)
-
-               plt.AddUint32(ctxt.Arch, uint32(rel.Size))
-
-               // jmp .plt
-               plt.AddUint8(0xe9)
-
-               plt.AddUint32(ctxt.Arch, uint32(-(plt.Size + 4)))
-
-               // rel
-               rel.AddAddrPlus(ctxt.Arch, got, got.Size-4)
-
-               rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_JMP_SLOT)))
-
-               s.SetPlt(int32(plt.Size - 16))
-       } else if ctxt.HeadType == objabi.Hdarwin {
-               // Same laziness as in 6l.
-
-               plt := ctxt.Syms.Lookup(".plt", 0)
-
-               addgotsym(ctxt, s)
-
-               ctxt.Syms.Lookup(".linkedit.plt", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
-
-               // jmpq *got+size(IP)
-               s.SetPlt(int32(plt.Size))
-
-               plt.AddUint8(0xff)
-               plt.AddUint8(0x25)
-               plt.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got()))
-       } else {
-               ld.Errorf(s, "addpltsym: unsupported binary format")
-       }
-}
-
-func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
-       if s.Got() >= 0 {
-               return
-       }
-
-       ld.Adddynsym(ctxt, s)
-       got := ctxt.Syms.Lookup(".got", 0)
-       s.SetGot(int32(got.Size))
-       got.AddUint32(ctxt.Arch, 0)
-
-       if ctxt.IsELF {
-               rel := ctxt.Syms.Lookup(".rel", 0)
-               rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
-               rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_GLOB_DAT)))
-       } else if ctxt.HeadType == objabi.Hdarwin {
-               ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
-       } else {
-               ld.Errorf(s, "addgotsym: unsupported binary format")
-       }
-}
-
-func asmb(ctxt *ld.Link) {
-       if ctxt.IsELF {
-               ld.Asmbelfsetup()
-       }
-
-       sect := ld.Segtext.Sections[0]
-       ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-       // 0xCC is INT $3 - breakpoint instruction
-       ld.CodeblkPad(ctxt, int64(sect.Vaddr), int64(sect.Length), []byte{0xCC})
-       for _, sect = range ld.Segtext.Sections[1:] {
-               ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
-               ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
-       }
-
-       if ld.Segrodata.Filelen > 0 {
-               ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
-               ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
-       }
-       if ld.Segrelrodata.Filelen > 0 {
-               ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
-               ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
-       }
-
-       ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
-       ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
-
-       ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
-       ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
-}
-
-func asmb2(ctxt *ld.Link) {
-       machlink := uint32(0)
-       if ctxt.HeadType == objabi.Hdarwin {
-               machlink = uint32(ld.Domacholink(ctxt))
-       }
-
-       ld.Symsize = 0
-       ld.Spsize = 0
-       ld.Lcsize = 0
-       symo := uint32(0)
-       if !*ld.FlagS {
-               // TODO: rationalize
-               switch ctxt.HeadType {
-               default:
-                       if ctxt.IsELF {
-                               symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-                               symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
-                       }
-
-               case objabi.Hplan9:
-                       symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
-
-               case objabi.Hdarwin:
-                       symo = uint32(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(*ld.FlagRound))) + uint64(machlink))
-
-               case objabi.Hwindows:
-                       symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
-                       symo = uint32(ld.Rnd(int64(symo), ld.PEFILEALIGN))
-               }
-
-               ctxt.Out.SeekSet(int64(symo))
-               switch ctxt.HeadType {
-               default:
-                       if ctxt.IsELF {
-                               ld.Asmelfsym(ctxt)
-                               ctxt.Out.Flush()
-                               ctxt.Out.Write(ld.Elfstrdat)
-
-                               if ctxt.LinkMode == ld.LinkExternal {
-                                       ld.Elfemitreloc(ctxt)
-                               }
-                       }
-
-               case objabi.Hplan9:
-                       ld.Asmplan9sym(ctxt)
-                       ctxt.Out.Flush()
-
-                       sym := ctxt.Syms.Lookup("pclntab", 0)
-                       if sym != nil {
-                               ld.Lcsize = int32(len(sym.P))
-                               ctxt.Out.Write(sym.P)
-                               ctxt.Out.Flush()
-                       }
-
-               case objabi.Hwindows:
-                       // Do nothing
-
-               case objabi.Hdarwin:
-                       if ctxt.LinkMode == ld.LinkExternal {
-                               ld.Machoemitreloc(ctxt)
-                       }
-               }
-       }
-
-       ctxt.Out.SeekSet(0)
-       switch ctxt.HeadType {
-       default:
-       case objabi.Hplan9: /* plan9 */
-               magic := int32(4*11*11 + 7)
-
-               ctxt.Out.Write32b(uint32(magic))              /* magic */
-               ctxt.Out.Write32b(uint32(ld.Segtext.Filelen)) /* sizes */
-               ctxt.Out.Write32b(uint32(ld.Segdata.Filelen))
-               ctxt.Out.Write32b(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
-               ctxt.Out.Write32b(uint32(ld.Symsize))          /* nsyms */
-               ctxt.Out.Write32b(uint32(ld.Entryvalue(ctxt))) /* va of entry */
-               ctxt.Out.Write32b(uint32(ld.Spsize))           /* sp offsets */
-               ctxt.Out.Write32b(uint32(ld.Lcsize))           /* line offsets */
-
-       case objabi.Hdarwin:
-               ld.Asmbmacho(ctxt)
-
-       case objabi.Hlinux,
-               objabi.Hfreebsd,
-               objabi.Hnetbsd,
-               objabi.Hopenbsd:
-               ld.Asmbelf(ctxt, int64(symo))
-
-       case objabi.Hwindows:
-               ld.Asmbpe(ctxt)
-       }
-
-       ctxt.Out.Flush()
-}
diff --git a/src/cmd/oldlink/internal/x86/l.go b/src/cmd/oldlink/internal/x86/l.go
deleted file mode 100644 (file)
index 0f104ea..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// Inferno utils/8l/l.h
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/8l/l.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package x86
-
-const (
-       maxAlign  = 32 // max data alignment
-       minAlign  = 1  // min data alignment
-       funcAlign = 16
-)
-
-/* Used by ../internal/ld/dwarf.go */
-const (
-       dwarfRegSP = 4
-       dwarfRegLR = 8
-)
diff --git a/src/cmd/oldlink/internal/x86/obj.go b/src/cmd/oldlink/internal/x86/obj.go
deleted file mode 100644 (file)
index b78ccba..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-// Inferno utils/8l/obj.c
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/8l/obj.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package x86
-
-import (
-       "cmd/internal/objabi"
-       "cmd/internal/sys"
-       "cmd/oldlink/internal/ld"
-)
-
-func Init() (*sys.Arch, ld.Arch) {
-       arch := sys.Arch386
-
-       theArch := ld.Arch{
-               Funcalign:  funcAlign,
-               Maxalign:   maxAlign,
-               Minalign:   minAlign,
-               Dwarfregsp: dwarfRegSP,
-               Dwarfreglr: dwarfRegLR,
-
-               Adddynrel:        adddynrel,
-               Archinit:         archinit,
-               Archreloc:        archreloc,
-               Archrelocvariant: archrelocvariant,
-               Asmb:             asmb,
-               Asmb2:            asmb2,
-               Elfreloc1:        elfreloc1,
-               Elfsetupplt:      elfsetupplt,
-               Gentext:          gentext,
-               Machoreloc1:      machoreloc1,
-               PEreloc1:         pereloc1,
-
-               Linuxdynld:   "/lib/ld-linux.so.2",
-               Freebsddynld: "/usr/libexec/ld-elf.so.1",
-               Openbsddynld: "/usr/libexec/ld.so",
-               Netbsddynld:  "/usr/libexec/ld.elf_so",
-               Solarisdynld: "/lib/ld.so.1",
-       }
-
-       return arch, theArch
-}
-
-func archinit(ctxt *ld.Link) {
-       switch ctxt.HeadType {
-       default:
-               ld.Exitf("unknown -H option: %v", ctxt.HeadType)
-
-       case objabi.Hplan9: /* plan 9 */
-               ld.HEADR = 32
-
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = 4096 + int64(ld.HEADR)
-               }
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 4096
-               }
-
-       case objabi.Hdarwin: /* apple MACH */
-               ld.HEADR = ld.INITIAL_MACHO_HEADR
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = 4096 + int64(ld.HEADR)
-               }
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 4096
-               }
-
-       case objabi.Hlinux, /* elf32 executable */
-               objabi.Hfreebsd,
-               objabi.Hnetbsd,
-               objabi.Hopenbsd:
-               ld.Elfinit(ctxt)
-
-               ld.HEADR = ld.ELFRESERVE
-               if *ld.FlagTextAddr == -1 {
-                       *ld.FlagTextAddr = 0x08048000 + int64(ld.HEADR)
-               }
-               if *ld.FlagRound == -1 {
-                       *ld.FlagRound = 4096
-               }
-
-       case objabi.Hwindows: /* PE executable */
-               // ld.HEADR, ld.FlagTextAddr, ld.FlagRound are set in ld.Peinit
-               return
-       }
-}
diff --git a/src/cmd/oldlink/main.go b/src/cmd/oldlink/main.go
deleted file mode 100644 (file)
index be1d0fd..0000000
+++ /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)
-}