]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.link] all: merge branch 'master' into dev.link
authorCherry Zhang <cherryyz@google.com>
Thu, 11 Jun 2020 20:49:19 +0000 (16:49 -0400)
committerCherry Zhang <cherryyz@google.com>
Thu, 11 Jun 2020 20:49:19 +0000 (16:49 -0400)
Change-Id: I446db56b20ef2189e23e225a91a17736c1d11e4c

1  2 
src/cmd/link/dwarf_test.go
src/cmd/link/internal/loader/loader.go

index 326f493e2dd6254ce435fb1894c4cf607865e662,a9f58db230a3f459bda45457426e68b9858d7072..ac6937ced02725a474e2b2b4f41d48d1681ca6a8
@@@ -33,8 -33,8 +33,8 @@@ func testDWARF(t *testing.T, buildmode 
                t.Fatalf("go list: %v\n%s", err, out)
        }
        if string(out) != "false\n" {
-               if os.Getenv("GOROOT_FINAL_OLD") != "" {
-                       t.Skip("cmd/link is stale, but $GOROOT_FINAL_OLD is set")
+               if strings.HasPrefix(testenv.Builder(), "darwin-") {
+                       t.Skipf("cmd/link is spuriously stale on Darwin builders - see #33598")
                }
                t.Fatalf("cmd/link is stale - run go install cmd/link")
        }
@@@ -191,13 -191,6 +191,13 @@@ func TestDWARFiOS(t *testing.T) 
        if err := exec.Command("xcrun", "--help").Run(); err != nil {
                t.Skipf("error running xcrun, required for iOS cross build: %v", err)
        }
 +      // Check to see if the ios tools are installed. It's possible to have the command line tools
 +      // installed without the iOS sdk.
 +      if output, err := exec.Command("xcodebuild -showsdks").CombinedOutput(); err != nil {
 +              t.Skipf("error running xcodebuild, required for iOS cross build: %v", err)
 +      } else if !strings.Contains(string(output), "iOS SDK") {
 +              t.Skipf("iOS SDK not detected.")
 +      }
        cc := "CC=" + runtime.GOROOT() + "/misc/ios/clangwrap.sh"
        // iOS doesn't allow unmapped segments, so iOS executables don't have DWARF.
        testDWARF(t, "", false, cc, "CGO_ENABLED=1", "GOOS=darwin", "GOARCH=arm64")
index 9b4214bdca6404909809a9eb30f27a46dbd20378,32c342e5456b5b17ea13cfd2f0a481c02c3580e0..f87776ef12b210e0034d95423ed67f748215a207
@@@ -33,7 -33,7 +33,7 @@@ type Sym in
  type Relocs struct {
        rs []goobj2.Reloc
  
 -      li int      // local index of symbol whose relocs we're examining
 +      li uint32   // local index of symbol whose relocs we're examining
        r  *oReader // object reader for containing package
        l  *Loader  // loader
  }
@@@ -125,12 -125,12 +125,12 @@@ type objIdx struct 
  
  // objSym represents a symbol in an object file. It is a tuple of
  // the object and the symbol's local index.
 -// For external symbols, r is l.extReader, s is its index into the
 -// payload array.
 -// {nil, 0} represents the nil symbol.
 +// For external symbols, objidx is the index of l.extReader (extObj),
 +// s is its index into the payload array.
 +// {0, 0} represents the nil symbol.
  type objSym struct {
 -      r *oReader
 -      s int // local index
 +      objidx uint32 // index of the object (in l.objs array)
 +      s      uint32 // local index
  }
  
  type nameVer struct {
@@@ -202,6 -202,13 +202,6 @@@ func growBitmap(reqLen int, b Bitmap) B
  //   extending the external symbol index space range. The host object
  //   loader stores symbol payloads in loader.payloads using SymbolBuilder.
  //
 -// - For now, in loader.LoadFull we convert all symbols (Go + external)
 -//   to sym.Symbols.
 -//
 -// - At some point (when the wayfront is pushed through all of the
 -//   linker), all external symbols will be payload-based, and we can
 -//   get rid of the loader.Syms array.
 -//
  // - Each symbol gets a unique global index. For duplicated and
  //   overwriting/overwritten symbols, the second (or later) appearance
  //   of the symbol gets the same global index as the first appearance.
@@@ -234,6 -241,9 +234,6 @@@ type Loader struct 
  
        objByPkg map[string]*oReader // map package path to its Go object reader
  
 -      Syms     []*sym.Symbol // indexed symbols. XXX we still make sym.Symbol for now.
 -      symBatch []sym.Symbol  // batch of symbols.
 -
        anonVersion int // most recently assigned ext static sym pseudo-version
  
        // Bitmaps and other side structures used to store data used to store
        // the symbol that triggered the marking of symbol K as live.
        Reachparent []Sym
  
 -      relocBatch    []sym.Reloc    // for bulk allocation of relocations
 -      relocExtBatch []sym.RelocExt // for bulk allocation of relocations
 -
        flags uint32
  
        strictDupMsgs int // number of strict-dup warning/errors, when FlagStrictDups is enabled
        elfsetstring elfsetstringFunc
  
        errorReporter *ErrorReporter
 -
 -      SymLookup func(name string, ver int) *sym.Symbol
  }
  
  const (
        nonPkgRef
  )
  
 -type elfsetstringFunc func(s *sym.Symbol, str string, off int)
 +// objidx
 +const (
 +      nilObj = iota
 +      extObj
 +      goObjStart
 +)
 +
 +type elfsetstringFunc func(str string, off int)
  
  // extSymPayload holds the payload (data + relocations) for linker-synthesized
  // external symbols (note that symbol value is stored in a separate slice).
@@@ -315,6 -323,7 +315,6 @@@ type extSymPayload struct 
        ver      int
        kind     sym.SymKind
        objidx   uint32 // index of original object if sym made by cloneToExternal
 -      gotype   Sym    // Gotype (0 if not present)
        relocs   []goobj2.Reloc
        reltypes []objabi.RelocType // relocation types
        data     []byte
@@@ -328,12 -337,11 +328,12 @@@ const 
  
  func NewLoader(flags uint32, elfsetstring elfsetstringFunc, reporter *ErrorReporter) *Loader {
        nbuiltin := goobj2.NBuiltin()
 +      extReader := &oReader{objidx: extObj}
        ldr := &Loader{
                start:                make(map[*oReader]Sym),
 -              objs:                 []objIdx{{}}, // reserve index 0 for nil symbol
 -              objSyms:              []objSym{{}}, // reserve index 0 for nil symbol
 -              extReader:            &oReader{},
 +              objs:                 []objIdx{{}, {extReader, 0}}, // reserve index 0 for nil symbol, 1 for external symbols
 +              objSyms:              make([]objSym, 1, 100000),    // reserve index 0 for nil symbol
 +              extReader:            extReader,
                symsByName:           [2]map[string]Sym{make(map[string]Sym, 100000), make(map[string]Sym, 50000)}, // preallocate ~2MB for ABI0 and ~1MB for ABI1 symbols
                objByPkg:             make(map[string]*oReader),
                outer:                make(map[Sym]Sym),
@@@ -384,13 -392,13 +384,13 @@@ func (l *Loader) addObj(pkg string, r *
  
  // Add a symbol from an object file, return the global index and whether it is added.
  // If the symbol already exist, it returns the index of that symbol.
 -func (l *Loader) AddSym(name string, ver int, r *oReader, li int, kind int, dupok bool, typ sym.SymKind) (Sym, bool) {
 +func (l *Loader) AddSym(name string, ver int, r *oReader, li uint32, kind int, dupok bool, typ sym.SymKind) (Sym, bool) {
        if l.extStart != 0 {
                panic("AddSym called after external symbol is created")
        }
        i := Sym(len(l.objSyms))
        addToGlobal := func() {
 -              l.objSyms = append(l.objSyms, objSym{r, li})
 +              l.objSyms = append(l.objSyms, objSym{r.objidx, li})
        }
        if name == "" {
                addToGlobal()
                if !(oldtyp.IsData() && oldr.DataSize(oldli) == 0) {
                        log.Fatalf("duplicated definition of symbol " + name)
                }
 -              l.objSyms[oldi] = objSym{r, li}
 +              l.objSyms[oldi] = objSym{r.objidx, li}
        } else {
                // old symbol overwrites new symbol.
                if !typ.IsData() { // only allow overwriting data symbol
@@@ -457,10 -465,9 +457,10 @@@ func (l *Loader) newExtSym(name string
        if l.extStart == 0 {
                l.extStart = i
        }
 -      l.growSyms(int(i))
 +      l.growValues(int(i) + 1)
 +      l.growAttrBitmaps(int(i) + 1)
        pi := l.newPayload(name, ver)
 -      l.objSyms = append(l.objSyms, objSym{l.extReader, int(pi)})
 +      l.objSyms = append(l.objSyms, objSym{l.extReader.objidx, uint32(pi)})
        l.extReader.syms = append(l.extReader.syms, i)
        return i
  }
@@@ -549,14 -556,25 +549,14 @@@ func (ms *extSymPayload) Grow(siz int64
        ms.data = ms.data[:siz]
  }
  
 -// Ensure Syms slice has enough space.
 -func (l *Loader) growSyms(i int) {
 -      n := len(l.Syms)
 -      if n > i {
 -              return
 -      }
 -      l.Syms = append(l.Syms, make([]*sym.Symbol, i+1-n)...)
 -      l.growValues(int(i) + 1)
 -      l.growAttrBitmaps(int(i) + 1)
 -}
 -
  // Convert a local index to a global index.
 -func (l *Loader) toGlobal(r *oReader, i int) Sym {
 +func (l *Loader) toGlobal(r *oReader, i uint32) Sym {
        return r.syms[i]
  }
  
  // Convert a global index to a local index.
 -func (l *Loader) toLocal(i Sym) (*oReader, int) {
 -      return l.objSyms[i].r, int(l.objSyms[i].s)
 +func (l *Loader) toLocal(i Sym) (*oReader, uint32) {
 +      return l.objs[l.objSyms[i].objidx].r, l.objSyms[i].s
  }
  
  // Resolve a local symbol reference. Return global index.
@@@ -589,7 -607,7 +589,7 @@@ func (l *Loader) resolve(r *oReader, s 
                        log.Fatalf("reference of nonexisted package %s, from %v", pkg, r.unit.Lib)
                }
        }
 -      return l.toGlobal(rr, int(s.SymIdx))
 +      return l.toGlobal(rr, s.SymIdx)
  }
  
  // Look up a symbol by name, return global index, or 0 if not found.
@@@ -603,7 -621,7 +603,7 @@@ func (l *Loader) Lookup(name string, ve
  }
  
  // Check that duplicate symbols have same contents.
 -func (l *Loader) checkdup(name string, r *oReader, li int, dup Sym) {
 +func (l *Loader) checkdup(name string, r *oReader, li uint32, dup Sym) {
        p := r.Data(li)
        rdup, ldup := l.toLocal(dup)
        pdup := rdup.Data(ldup)
        }
        fmt.Fprintf(os.Stderr, "cmd/link: while reading object for '%v': duplicate symbol '%s', previous def at '%v', with mismatched payload: %s\n", r.unit.Lib, name, rdup.unit.Lib, reason)
  
-       // For the moment, whitelist DWARF subprogram DIEs for
+       // For the moment, allow 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(name, "go.info.go.interface") ||
+       allowed := strings.HasPrefix(name, "go.info.go.interface") ||
                strings.HasPrefix(name, "go.info.go.builtin") ||
                strings.HasPrefix(name, "go.debuglines")
-       if !whitelist {
+       if !allowed {
                l.strictDupMsgs++
        }
  }
@@@ -663,11 -681,7 +663,11 @@@ func (l *Loader) SymName(i Sym) string 
                return pp.name
        }
        r, li := l.toLocal(i)
 -      return strings.Replace(r.Sym(li).Name(r.Reader), "\"\".", r.pkgprefix, -1)
 +      name := r.Sym(li).Name(r.Reader)
 +      if !r.NeedNameExpansion() {
 +              return name
 +      }
 +      return strings.Replace(name, "\"\".", r.pkgprefix, -1)
  }
  
  // Returns the version of the i-th symbol.
@@@ -680,8 -694,6 +680,8 @@@ func (l *Loader) SymVersion(i Sym) int 
        return int(abiToVer(r.Sym(li).ABI(), r.version))
  }
  
 +func (l *Loader) IsFileLocal(i Sym) bool { return l.SymVersion(i) >= sym.SymVerStatic }
 +
  // Returns the type of the i-th symbol.
  func (l *Loader) SymType(i Sym) sym.SymKind {
        if l.IsExternal(i) {
@@@ -849,7 -861,7 +849,7 @@@ func (l *Loader) AttrShared(i Sym) boo
                // might make more sense to copy the flag value out of the
                // object into a larger bitmap during preload.
                r, _ := l.toLocal(i)
 -              return (r.Flags() & goobj2.ObjFlagShared) != 0
 +              return r.Shared()
        }
        return l.attrShared.Has(l.extIndex(i))
  }
@@@ -1178,7 -1190,7 +1178,7 @@@ func (l *Loader) SymSect(i Sym) *sym.Se
        return l.sects[l.symSects[i]]
  }
  
 -// SetSymValue sets the section of the i-th symbol. i is global index.
 +// SetSymSect sets the section of the i-th symbol. i is global index.
  func (l *Loader) SetSymSect(i Sym, sect *sym.Section) {
        if int(i) >= len(l.symSects) {
                l.symSects = append(l.symSects, make([]uint16, l.NSym()-len(l.symSects))...)
@@@ -1408,17 -1420,12 +1408,17 @@@ func (l *Loader) DynidSyms() []Sym 
  // results in to a map (might want to try this at some point and see
  // if it helps speed things up).
  func (l *Loader) SymGoType(i Sym) Sym {
 +      var r *oReader
 +      var auxs []goobj2.Aux
        if l.IsExternal(i) {
                pp := l.getPayload(i)
 -              return pp.gotype
 +              r = l.objs[pp.objidx].r
 +              auxs = pp.auxs
 +      } else {
 +              var li uint32
 +              r, li = l.toLocal(i)
 +              auxs = r.Auxs(li)
        }
 -      r, li := l.toLocal(i)
 -      auxs := r.Auxs(li)
        for j := range auxs {
                a := &auxs[j]
                switch a.Type() {
@@@ -1539,7 -1546,7 +1539,7 @@@ func (l *Loader) GetFuncDwarfAuxSyms(fn
                switch a.Type() {
                case goobj2.AuxDwarfInfo:
                        auxDwarfInfo = l.resolve(r, a.Sym())
 -                      if l.SymType(auxDwarfInfo) != sym.SDWARFINFO {
 +                      if l.SymType(auxDwarfInfo) != sym.SDWARFFCN {
                                panic("aux dwarf info sym with wrong type")
                        }
                case goobj2.AuxDwarfLoc:
@@@ -1601,11 -1608,6 +1601,11 @@@ func (l *Loader) SubSym(i Sym) Sym 
  func (l *Loader) SetOuterSym(i Sym, o Sym) {
        if o != 0 {
                l.outer[i] = o
 +              // relocsym's foldSubSymbolOffset requires that we only
 +              // have a single level of containment-- enforce here.
 +              if l.outer[o] != 0 {
 +                      panic("multiply nested outer sym")
 +              }
        } else {
                delete(l.outer, i)
        }
@@@ -1701,7 -1703,7 +1701,7 @@@ func (l *Loader) Relocs(i Sym) Relocs 
  }
  
  // Relocs returns a Relocs object given a local sym index and reader.
 -func (l *Loader) relocs(r *oReader, li int) Relocs {
 +func (l *Loader) relocs(r *oReader, li uint32) Relocs {
        var rs []goobj2.Reloc
        if l.isExtReader(r) {
                pp := l.payloads[li]
@@@ -1893,14 -1895,14 +1893,14 @@@ func (l *Loader) FuncInfo(i Sym) FuncIn
                r = l.objs[pp.objidx].r
                auxs = pp.auxs
        } else {
 -              var li int
 +              var li uint32
                r, li = l.toLocal(i)
                auxs = r.Auxs(li)
        }
        for j := range auxs {
                a := &auxs[j]
                if a.Type() == goobj2.AuxFuncInfo {
 -                      b := r.Data(int(a.Sym().SymIdx))
 +                      b := r.Data(a.Sym().SymIdx)
                        return FuncInfo{l, r, b, auxs, goobj2.FuncInfoLengths{}}
                }
        }
  // Does not add non-package symbols yet, which will be done in LoadNonpkgSyms.
  // Does not read symbol data.
  // Returns the fingerprint of the object.
 -func (l *Loader) Preload(syms *sym.Symbols, f *bio.Reader, lib *sym.Library, unit *sym.CompilationUnit, length int64) goobj2.FingerprintType {
 +func (l *Loader) Preload(localSymVersion int, f *bio.Reader, lib *sym.Library, unit *sym.CompilationUnit, length int64) goobj2.FingerprintType {
        roObject, readonly, err := f.Slice(uint64(length)) // TODO: no need to map blocks that are for tools only (e.g. RefName)
        if err != nil {
                log.Fatal("cannot read object file:", err)
        r := goobj2.NewReaderFromBytes(roObject, readonly)
        if r == nil {
                if len(roObject) >= 8 && bytes.Equal(roObject[:8], []byte("\x00go114ld")) {
 -                      log.Fatalf("found object file %s in old format, but -go115newobj is true\nset -go115newobj consistently in all -gcflags, -asmflags, and -ldflags", f.File().Name())
 +                      log.Fatalf("found object file %s in old format", f.File().Name())
                }
                panic("cannot read object file")
        }
 -      localSymVersion := syms.IncVersion()
        pkgprefix := objabi.PathToPrefix(lib.Pkg) + "."
        ndef := r.NSym()
        nnonpkgdef := r.NNonpkgdef()
  
  // Preload symbols of given kind from an object.
  func (l *Loader) preloadSyms(r *oReader, kind int) {
 -      ndef := r.NSym()
 -      nnonpkgdef := r.NNonpkgdef()
 -      var start, end int
 +      ndef := uint32(r.NSym())
 +      nnonpkgdef := uint32(r.NNonpkgdef())
 +      var start, end uint32
        switch kind {
        case pkgDef:
                start = 0
        default:
                panic("preloadSyms: bad kind")
        }
 -      l.growSyms(len(l.objSyms) + end - start)
 -      l.growAttrBitmaps(len(l.objSyms) + end - start)
 +      l.growAttrBitmaps(len(l.objSyms) + int(end-start))
 +      needNameExpansion := r.NeedNameExpansion()
        for i := start; i < end; i++ {
                osym := r.Sym(i)
 -              name := strings.Replace(osym.Name(r.Reader), "\"\".", r.pkgprefix, -1)
 +              name := osym.Name(r.Reader)
 +              if needNameExpansion {
 +                      name = strings.Replace(name, "\"\".", r.pkgprefix, -1)
 +              }
                v := abiToVer(osym.ABI(), r.version)
                dupok := osym.Dupok()
                gi, added := l.AddSym(name, v, r, i, kind, dupok, sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type())])
                                l.builtinSyms[bi] = gi
                        }
                }
 -              if strings.HasPrefix(name, "go.string.") ||
 -                      strings.HasPrefix(name, "gclocals·") ||
 -                      strings.HasPrefix(name, "runtime.gcbits.") {
 -                      l.SetAttrNotInSymbolTable(gi, true)
 -              }
                if a := osym.Align(); a != 0 {
                        l.SetSymAlign(gi, int32(a))
                }
  // Add non-package symbols and references to external symbols (which are always
  // named).
  func (l *Loader) LoadNonpkgSyms(arch *sys.Arch) {
 -      for _, o := range l.objs[1:] {
 +      for _, o := range l.objs[goObjStart:] {
                l.preloadSyms(o.r, nonPkgDef)
        }
 -      for _, o := range l.objs[1:] {
 +      for _, o := range l.objs[goObjStart:] {
                loadObjRefs(l, o.r, arch)
        }
 +      l.values = make([]int64, l.NSym(), l.NSym()+1000) // +1000 make some room for external symbols
  }
  
  func loadObjRefs(l *Loader, r *oReader, arch *sys.Arch) {
 -      ndef := r.NSym() + r.NNonpkgdef()
 -      for i, n := 0, r.NNonpkgref(); i < n; i++ {
 +      ndef := uint32(r.NSym() + r.NNonpkgdef())
 +      needNameExpansion := r.NeedNameExpansion()
 +      for i, n := uint32(0), uint32(r.NNonpkgref()); i < n; i++ {
                osym := r.Sym(ndef + i)
 -              name := strings.Replace(osym.Name(r.Reader), "\"\".", r.pkgprefix, -1)
 +              name := osym.Name(r.Reader)
 +              if needNameExpansion {
 +                      name = strings.Replace(name, "\"\".", r.pkgprefix, -1)
 +              }
                v := abiToVer(osym.ABI(), r.version)
                r.syms[ndef+i] = l.LookupOrCreateSym(name, v)
                gi := r.syms[ndef+i]
@@@ -2070,6 -2070,163 +2070,6 @@@ func (l *Loader) preprocess(arch *sys.A
        }
  }
  
 -// Load full contents.
 -func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols, needReloc, needExtReloc bool) {
 -      // create all Symbols first.
 -      l.growSyms(l.NSym())
 -      l.growSects(l.NSym())
 -
 -      if needReloc && len(l.extRelocs) != 0 {
 -              // If needReloc is true, we are going to convert the loader's
 -              // "internal" relocations to sym.Relocs. In this case, external
 -              // relocations shouldn't be used.
 -              panic("phase error")
 -      }
 -
 -      nr := 0 // total number of sym.Reloc's we'll need
 -      for _, o := range l.objs[1:] {
 -              nr += loadObjSyms(l, syms, o.r, needReloc, needExtReloc)
 -      }
 -
 -      // Make a first pass through the external symbols, making
 -      // sure that each external symbol has a non-nil entry in
 -      // l.Syms (note that relocations and symbol content will
 -      // be copied in a later loop).
 -      toConvert := make([]Sym, 0, len(l.payloads))
 -      for _, i := range l.extReader.syms {
 -              if !l.attrReachable.Has(i) {
 -                      continue
 -              }
 -              pp := l.getPayload(i)
 -              if needReloc {
 -                      nr += len(pp.relocs)
 -              }
 -              if needExtReloc && int(i) < len(l.extRelocs) {
 -                      nr += len(l.extRelocs[i])
 -              }
 -              // create and install the sym.Symbol here so that l.Syms will
 -              // be fully populated when we do relocation processing and
 -              // outer/sub processing below. Note that once we do this,
 -              // we'll need to get at the payload for a symbol with direct
 -              // reference to l.payloads[] as opposed to calling l.getPayload().
 -              s := l.allocSym(pp.name, 0)
 -              l.installSym(i, s)
 -              toConvert = append(toConvert, i)
 -      }
 -
 -      // allocate a single large slab of relocations for all live symbols
 -      if nr != 0 {
 -              l.relocBatch = make([]sym.Reloc, nr)
 -              if needExtReloc {
 -                      l.relocExtBatch = make([]sym.RelocExt, nr)
 -              }
 -      }
 -
 -      // convert payload-based external symbols into sym.Symbol-based
 -      for _, i := range toConvert {
 -
 -              // Copy kind/size/value etc.
 -              pp := l.payloads[l.extIndex(i)]
 -              s := l.Syms[i]
 -              s.Version = int16(pp.ver)
 -              s.Type = pp.kind
 -              s.Size = pp.size
 -
 -              // Copy relocations
 -              if needReloc {
 -                      batch := l.relocBatch
 -                      s.R = batch[:len(pp.relocs):len(pp.relocs)]
 -                      l.relocBatch = batch[len(pp.relocs):]
 -                      relocs := l.Relocs(i)
 -                      l.convertRelocations(i, &relocs, s, false)
 -              }
 -              if needExtReloc {
 -                      l.convertExtRelocs(s, i)
 -              }
 -
 -              // Copy data
 -              s.P = pp.data
 -
 -              // Transfer over attributes.
 -              l.migrateAttributes(i, s)
 -      }
 -
 -      // load contents of defined symbols
 -      for _, o := range l.objs[1:] {
 -              loadObjFull(l, o.r, needReloc, needExtReloc)
 -      }
 -
 -      // Sanity check: we should have consumed all batched allocations.
 -      if len(l.relocBatch) != 0 || len(l.relocExtBatch) != 0 {
 -              panic("batch allocation mismatch")
 -      }
 -
 -      // Note: resolution of ABI aliases is now also handled in
 -      // loader.convertRelocations, so once the host object loaders move
 -      // completely to loader.Sym, we can remove the code below.
 -
 -      // Resolve ABI aliases for external symbols. This is only
 -      // needed for internal cgo linking.
 -      if needReloc {
 -              for _, i := range l.extReader.syms {
 -                      if s := l.Syms[i]; s != nil && s.Attr.Reachable() {
 -                              for ri := range s.R {
 -                                      r := &s.R[ri]
 -                                      if r.Sym != nil && r.Sym.Type == sym.SABIALIAS {
 -                                              r.Sym = r.Sym.R[0].Sym
 -                                      }
 -                              }
 -                      }
 -              }
 -      }
 -
 -      // Free some memory.
 -      // At this point we still need basic index mapping, and some fields of
 -      // external symbol payloads, but not much else.
 -      l.values = nil
 -      l.symSects = nil
 -      l.outdata = nil
 -      l.itablink = nil
 -      l.attrOnList = nil
 -      l.attrLocal = nil
 -      l.attrNotInSymbolTable = nil
 -      l.attrVisibilityHidden = nil
 -      l.attrDuplicateOK = nil
 -      l.attrShared = nil
 -      l.attrExternal = nil
 -      l.attrReadOnly = nil
 -      l.attrTopFrame = nil
 -      l.attrSpecial = nil
 -      l.attrCgoExportDynamic = nil
 -      l.attrCgoExportStatic = nil
 -      l.outer = nil
 -      l.align = nil
 -      l.dynimplib = nil
 -      l.dynimpvers = nil
 -      l.localentry = nil
 -      l.extname = nil
 -      l.elfType = nil
 -      l.plt = nil
 -      l.got = nil
 -      l.dynid = nil
 -      if needExtReloc { // converted to sym.Relocs, drop loader references
 -              l.relocVariant = nil
 -              l.extRelocs = nil
 -      }
 -
 -      // Drop fields that are no longer needed.
 -      for _, i := range l.extReader.syms {
 -              pp := l.getPayload(i)
 -              pp.name = ""
 -              pp.auxs = nil
 -              pp.data = nil
 -              if needExtReloc {
 -                      pp.relocs = nil
 -                      pp.reltypes = nil
 -              }
 -      }
 -}
 -
  // ResolveABIAlias given a symbol returns the ABI alias target of that
  // symbol. If the sym in question is not an alias, the sym itself is
  // returned.
@@@ -2088,6 -2245,227 +2088,6 @@@ func (l *Loader) ResolveABIAlias(s Sym
        return target
  }
  
 -// PropagateSymbolChangesBackToLoader is a temporary shim function
 -// that copies over a given sym.Symbol into the equivalent representation
 -// in the loader world. The intent is to enable converting a given
 -// linker phase/pass from dealing with sym.Symbol's to a modernized
 -// pass that works with loader.Sym, in cases where the "loader.Sym
 -// wavefront" has not yet reached the pass in question. For such work
 -// the recipe is to first call PropagateSymbolChangesBackToLoader(),
 -// then exexute the pass working with the loader, then call
 -// PropagateLoaderChangesToSymbols to copy the changes made by the
 -// pass back to the sym.Symbol world.
 -func (l *Loader) PropagateSymbolChangesBackToLoader() {
 -
 -      // For the moment we only copy symbol values, and we don't touch
 -      // any new sym.Symbols created since loadlibfull() was run. This
 -      // seems to be what's needed for DWARF gen.
 -      for i := Sym(1); i < Sym(len(l.objSyms)); i++ {
 -              s := l.Syms[i]
 -              if s != nil {
 -                      if s.Value != l.SymValue(i) {
 -                              l.SetSymValue(i, s.Value)
 -                      }
 -              }
 -      }
 -}
 -
 -// PropagateLoaderChangesToSymbols is a temporary shim function that
 -// takes a list of loader.Sym symbols and works to copy their contents
 -// and attributes over to a corresponding sym.Symbol. The parameter
 -// anonVerReplacement specifies a version number for any new anonymous
 -// symbols encountered on the list, when creating sym.Symbols for them
 -// (or zero if we don't expect to encounter any new anon symbols). See
 -// the PropagateSymbolChangesBackToLoader header comment for more
 -// info.
 -//
 -// WARNING: this function is brittle and depends heavily on loader
 -// implementation. A key problem with doing this is that as things
 -// stand at the moment, some sym.Symbol contents/attributes are
 -// populated only when converting from loader.Sym to sym.Symbol in
 -// loadlibfull, meaning we may wipe out some information when copying
 -// back.
 -
 -func (l *Loader) PropagateLoaderChangesToSymbols(toconvert []Sym, anonVerReplacement int) []*sym.Symbol {
 -
 -      result := []*sym.Symbol{}
 -      relocfixup := []Sym{}
 -
 -      // Note: this loop needs to allow for the possibility that we may
 -      // see "new" symbols on the 'toconvert' list that come from object
 -      // files (for example, DWARF location lists), as opposed to just
 -      // newly manufactured symbols (ex: DWARF section symbols such as
 -      // ".debug_info").  This means that we have to be careful not to
 -      // stomp on sym.Symbol attributes/content that was set up in
 -      // in loadlibfull().
 -
 -      // Also note that in order for the relocation fixup to work, we
 -      // have to do this in two passes -- one pass to create the symbols,
 -      // and then a second fix up the relocations once all necessary
 -      // sym.Symbols are created.
 -
 -      // First pass, symbol creation and symbol data fixup.
 -      for _, cand := range toconvert {
 -
 -              sn := l.SymName(cand)
 -              sv := l.SymVersion(cand)
 -              st := l.SymType(cand)
 -              if sv < 0 {
 -                      if anonVerReplacement == 0 {
 -                              panic("expected valid anon version replacement")
 -                      }
 -                      sv = anonVerReplacement
 -              }
 -
 -              s := l.Syms[cand]
 -
 -              isnew := false
 -              if sn == "" {
 -                      // Don't install anonymous symbols in the lookup tab.
 -                      if s == nil {
 -                              s = l.allocSym(sn, sv)
 -                              l.installSym(cand, s)
 -                      }
 -                      isnew = true
 -              } else {
 -                      if s != nil {
 -                              // Already have a symbol for this -- it must be
 -                              // something that was previously processed by
 -                              // loadObjFull. Note that the symbol in question may
 -                              // or may not be in the name lookup map.
 -                      } else {
 -                              isnew = true
 -                              s = l.SymLookup(sn, sv)
 -                      }
 -              }
 -              result = append(result, s)
 -
 -              // Always copy these from new to old.
 -              s.Value = l.SymValue(cand)
 -              s.Type = st
 -
 -              // If the data for a symbol has increased in size, make sure
 -              // we bring the new content across.
 -              relfix := isnew
 -              if isnew || len(l.Data(cand)) > len(s.P) {
 -                      s.P = l.Data(cand)
 -                      s.Size = int64(len(s.P))
 -                      relfix = true
 -              }
 -
 -              // For 'new' symbols, copy other content.
 -              if relfix {
 -                      relocfixup = append(relocfixup, cand)
 -              }
 -
 -              // If new symbol, call a helper to migrate attributes.
 -              // Otherwise touch only not-in-symbol-table, since there are
 -              // some attrs that are only set up at the point where we
 -              // convert loader.Sym to sym.Symbol.
 -              if isnew {
 -                      l.migrateAttributes(cand, s)
 -              } else {
 -                      if l.AttrNotInSymbolTable(cand) {
 -                              s.Attr.Set(sym.AttrNotInSymbolTable, true)
 -                      }
 -              }
 -      }
 -
 -      // Second pass to fix up relocations.
 -      for _, cand := range relocfixup {
 -              s := l.Syms[cand]
 -              relocs := l.Relocs(cand)
 -              if len(s.R) != relocs.Count() {
 -                      s.R = make([]sym.Reloc, relocs.Count())
 -              }
 -              l.convertRelocations(cand, &relocs, s, true)
 -      }
 -
 -      return result
 -}
 -
 -// ExtractSymbols grabs the symbols out of the loader for work that hasn't been
 -// ported to the new symbol type.
 -func (l *Loader) ExtractSymbols(syms *sym.Symbols) {
 -      // Add symbols to the ctxt.Syms lookup table. This explicitly skips things
 -      // created via loader.Create (marked with versions less than zero), since
 -      // if we tried to add these we'd wind up with collisions. We do, however,
 -      // add these symbols to the list of global symbols so that other future
 -      // steps (like pclntab generation) can find these symbols if neceassary.
 -      // Along the way, update the version from the negative anon version to
 -      // something larger than sym.SymVerStatic (needed so that
 -      // sym.symbol.IsFileLocal() works properly).
 -      anonVerReplacement := syms.IncVersion()
 -      for _, s := range l.Syms {
 -              if s == nil {
 -                      continue
 -              }
 -              if s.Version < 0 {
 -                      s.Version = int16(anonVerReplacement)
 -              }
 -      }
 -
 -      // Provide lookup functions for sym.Symbols.
 -      l.SymLookup = func(name string, ver int) *sym.Symbol {
 -              i := l.LookupOrCreateSym(name, ver)
 -              if s := l.Syms[i]; s != nil {
 -                      return s
 -              }
 -              s := l.allocSym(name, ver)
 -              l.installSym(i, s)
 -              return s
 -      }
 -      syms.Lookup = l.SymLookup
 -      syms.ROLookup = func(name string, ver int) *sym.Symbol {
 -              i := l.Lookup(name, ver)
 -              return l.Syms[i]
 -      }
 -}
 -
 -// allocSym allocates a new symbol backing.
 -func (l *Loader) allocSym(name string, version int) *sym.Symbol {
 -      batch := l.symBatch
 -      if len(batch) == 0 {
 -              batch = make([]sym.Symbol, 1000)
 -      }
 -      s := &batch[0]
 -      l.symBatch = batch[1:]
 -
 -      s.Dynid = -1
 -      s.Name = name
 -      s.Version = int16(version)
 -
 -      return s
 -}
 -
 -// installSym sets the underlying sym.Symbol for the specified sym index.
 -func (l *Loader) installSym(i Sym, s *sym.Symbol) {
 -      if s == nil {
 -              panic("installSym nil symbol")
 -      }
 -      if l.Syms[i] != nil {
 -              panic("sym already present in installSym")
 -      }
 -      l.Syms[i] = s
 -      s.SymIdx = sym.LoaderSym(i)
 -}
 -
 -// addNewSym adds a new sym.Symbol to the i-th index in the list of symbols.
 -func (l *Loader) addNewSym(i Sym, name string, ver int, unit *sym.CompilationUnit, t sym.SymKind) *sym.Symbol {
 -      s := l.allocSym(name, ver)
 -      if s.Type != 0 && s.Type != sym.SXREF {
 -              fmt.Println("symbol already processed:", unit.Lib, i, s)
 -              panic("symbol already processed")
 -      }
 -      if t == sym.SBSS && (s.Type == sym.SRODATA || s.Type == sym.SNOPTRBSS) {
 -              t = s.Type
 -      }
 -      s.Type = t
 -      l.growSyms(int(i))
 -      l.installSym(i, s)
 -      return s
 -}
 -
  // TopLevelSym tests a symbol (by name and kind) to determine whether
  // the symbol first class sym (participating in the link) or is an
  // anonymous aux or sub-symbol containing some sub-part or payload of
@@@ -2105,13 -2483,56 +2105,13 @@@ func topLevelSym(sname string, skind sy
                return true
        }
        switch skind {
 -      case sym.SDWARFINFO, sym.SDWARFRANGE, sym.SDWARFLOC, sym.SDWARFLINES, sym.SGOFUNC:
 +      case sym.SDWARFFCN, sym.SDWARFABSFCN, sym.SDWARFTYPE, sym.SDWARFCONST, sym.SDWARFCUINFO, sym.SDWARFRANGE, sym.SDWARFLOC, sym.SDWARFLINES, sym.SGOFUNC:
                return true
        default:
                return false
        }
  }
  
 -// loadObjSyms creates sym.Symbol objects for the live Syms in the
 -// object corresponding to object reader "r". Return value is the
 -// number of sym.Reloc entries required for all the new symbols.
 -func loadObjSyms(l *Loader, syms *sym.Symbols, r *oReader, needReloc, needExtReloc bool) int {
 -      nr := 0
 -      for i, n := 0, r.NSym()+r.NNonpkgdef(); i < n; i++ {
 -              gi := r.syms[i]
 -              if r2, i2 := l.toLocal(gi); r2 != r || i2 != i {
 -                      continue // come from a different object
 -              }
 -              osym := r.Sym(i)
 -              name := strings.Replace(osym.Name(r.Reader), "\"\".", r.pkgprefix, -1)
 -              t := sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type())]
 -
 -              // Skip non-dwarf anonymous symbols (e.g. funcdata),
 -              // since they will never be turned into sym.Symbols.
 -              if !topLevelSym(name, t) {
 -                      continue
 -              }
 -              ver := abiToVer(osym.ABI(), r.version)
 -              if t == sym.SXREF {
 -                      log.Fatalf("bad sxref")
 -              }
 -              if t == 0 {
 -                      log.Fatalf("missing type for %s in %s", name, r.unit.Lib)
 -              }
 -              if !l.attrReachable.Has(gi) && name != "runtime.addmoduledata" && name != "runtime.lastmoduledatap" {
 -                      // No need to load unreachable symbols.
 -                      // XXX reference to runtime.addmoduledata may be generated later by the linker in plugin mode.
 -                      continue
 -              }
 -
 -              l.addNewSym(gi, name, ver, r.unit, t)
 -              if needReloc {
 -                      nr += r.NReloc(i)
 -              }
 -              if needExtReloc && int(gi) < len(l.extRelocs) {
 -                      nr += len(l.extRelocs[gi])
 -              }
 -      }
 -      return nr
 -}
 -
  // cloneToExternal takes the existing object file symbol (symIdx)
  // and creates a new external symbol payload that is a clone with
  // respect to name, version, type, relocations, etc. The idea here
  // a symbol originally discovered as part of an object file, it's
  // easier to do this if we make the updates to an external symbol
  // payload.
 -// XXX maybe rename? makeExtPayload?
  func (l *Loader) cloneToExternal(symIdx Sym) {
        if l.IsExternal(symIdx) {
                panic("sym is already external, no need for clone")
        }
 -      l.growSyms(int(symIdx))
  
        // Read the particulars from object.
        r, li := l.toLocal(symIdx)
        osym := r.Sym(li)
 -      sname := strings.Replace(osym.Name(r.Reader), "\"\".", r.pkgprefix, -1)
 +      sname := osym.Name(r.Reader)
 +      if r.NeedNameExpansion() {
 +              sname = strings.Replace(sname, "\"\".", r.pkgprefix, -1)
 +      }
        sver := abiToVer(osym.ABI(), r.version)
        skind := sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type())]
  
  
        // If this is a def, then copy the guts. We expect this case
        // to be very rare (one case it may come up is with -X).
 -      if li < (r.NSym() + r.NNonpkgdef()) {
 +      if li < uint32(r.NSym()+r.NNonpkgdef()) {
  
                // Copy relocations
                relocs := l.Relocs(symIdx)
        // Gotype, so as to propagate it to the new symbol.
        auxs := r.Auxs(li)
        pp.auxs = auxs
 -loop:
 -      for j := range auxs {
 -              a := &auxs[j]
 -              switch a.Type() {
 -              case goobj2.AuxGotype:
 -                      pp.gotype = l.resolve(r, a.Sym())
 -                      break loop
 -              default:
 -                      // nothing to do
 -              }
 -      }
  
        // Install new payload to global index space.
        // (This needs to happen at the end, as the accessors above
        // need to access the old symbol content.)
 -      l.objSyms[symIdx] = objSym{l.extReader, pi}
 +      l.objSyms[symIdx] = objSym{l.extReader.objidx, uint32(pi)}
        l.extReader.syms = append(l.extReader.syms, symIdx)
  }
  
@@@ -2218,6 -2649,67 +2218,6 @@@ func (l *Loader) CopyAttributes(src Sym
        l.SetAttrReadOnly(dst, l.AttrReadOnly(src))
  }
  
 -// migrateAttributes copies over all of the attributes of symbol 'src' to
 -// sym.Symbol 'dst'.
 -func (l *Loader) migrateAttributes(src Sym, dst *sym.Symbol) {
 -      dst.Value = l.SymValue(src)
 -      dst.Align = l.SymAlign(src)
 -      dst.Sect = l.SymSect(src)
 -
 -      dst.Attr.Set(sym.AttrReachable, l.AttrReachable(src))
 -      dst.Attr.Set(sym.AttrOnList, l.AttrOnList(src))
 -      dst.Attr.Set(sym.AttrLocal, l.AttrLocal(src))
 -      dst.Attr.Set(sym.AttrNotInSymbolTable, l.AttrNotInSymbolTable(src))
 -      dst.Attr.Set(sym.AttrNoSplit, l.IsNoSplit(src))
 -      dst.Attr.Set(sym.AttrVisibilityHidden, l.AttrVisibilityHidden(src))
 -      dst.Attr.Set(sym.AttrDuplicateOK, l.AttrDuplicateOK(src))
 -      dst.Attr.Set(sym.AttrShared, l.AttrShared(src))
 -      dst.Attr.Set(sym.AttrExternal, l.AttrExternal(src))
 -      dst.Attr.Set(sym.AttrTopFrame, l.AttrTopFrame(src))
 -      dst.Attr.Set(sym.AttrSpecial, l.AttrSpecial(src))
 -      dst.Attr.Set(sym.AttrCgoExportDynamic, l.AttrCgoExportDynamic(src))
 -      dst.Attr.Set(sym.AttrCgoExportStatic, l.AttrCgoExportStatic(src))
 -      dst.Attr.Set(sym.AttrReadOnly, l.AttrReadOnly(src))
 -
 -      // Convert outer relationship
 -      if outer, ok := l.outer[src]; ok {
 -              dst.Outer = l.Syms[outer]
 -      }
 -
 -      // Set sub-symbol attribute. See the comment on the AttrSubSymbol
 -      // method for more on this, there is some tricky stuff here.
 -      dst.Attr.Set(sym.AttrSubSymbol, l.outer[src] != 0 && l.sub[l.outer[src]] != 0)
 -
 -      // Copy over dynimplib, dynimpvers, extname.
 -      if name, ok := l.extname[src]; ok {
 -              dst.SetExtname(name)
 -      }
 -      if l.SymDynimplib(src) != "" {
 -              dst.SetDynimplib(l.SymDynimplib(src))
 -      }
 -      if l.SymDynimpvers(src) != "" {
 -              dst.SetDynimpvers(l.SymDynimpvers(src))
 -      }
 -
 -      // Copy ELF type if set.
 -      if et, ok := l.elfType[src]; ok {
 -              dst.SetElfType(et)
 -      }
 -
 -      // Copy pe objects values if set.
 -      if plt, ok := l.plt[src]; ok {
 -              dst.SetPlt(plt)
 -      }
 -      if got, ok := l.got[src]; ok {
 -              dst.SetGot(got)
 -      }
 -
 -      // Copy dynid
 -      if dynid, ok := l.dynid[src]; ok {
 -              dst.Dynid = dynid
 -      }
 -}
 -
  // CreateExtSym creates a new external symbol with the specified name
  // without adding it to any lookup tables, returning a Sym index for it.
  func (l *Loader) CreateExtSym(name string, ver int) Sym {
  // without adding it to any lookup tables, returning a Sym index for it.
  func (l *Loader) CreateStaticSym(name string) Sym {
        // Assign a new unique negative version -- this is to mark the
 -      // symbol so that it can be skipped when ExtractSymbols is adding
 -      // ext syms to the sym.Symbols hash.
 +      // symbol so that it is not included in the name lookup table.
        l.anonVersion--
        return l.newExtSym(name, l.anonVersion)
  }
@@@ -2240,6 -2733,144 +2240,6 @@@ func (l *Loader) FreeSym(i Sym) 
        }
  }
  
 -func loadObjFull(l *Loader, r *oReader, needReloc, needExtReloc bool) {
 -      for i, n := 0, r.NSym()+r.NNonpkgdef(); i < n; i++ {
 -              // A symbol may be a dup or overwritten. In this case, its
 -              // content will actually be provided by a different object
 -              // (to which its global index points). Skip those symbols.
 -              gi := l.toGlobal(r, i)
 -              if r2, i2 := l.toLocal(gi); r2 != r || i2 != i {
 -                      continue
 -              }
 -              s := l.Syms[gi]
 -              if s == nil {
 -                      continue
 -              }
 -
 -              l.migrateAttributes(gi, s)
 -              // Be careful not to overwrite attributes set by the linker.
 -              // Don't use the attributes from the object file.
 -
 -              osym := r.Sym(i)
 -              size := osym.Siz()
 -
 -              // Symbol data
 -              s.P = l.OutData(gi)
 -
 -              // Relocs
 -              if needReloc {
 -                      relocs := l.relocs(r, i)
 -                      batch := l.relocBatch
 -                      s.R = batch[:relocs.Count():relocs.Count()]
 -                      l.relocBatch = batch[relocs.Count():]
 -                      l.convertRelocations(gi, &relocs, s, false)
 -              }
 -              if needExtReloc {
 -                      l.convertExtRelocs(s, gi)
 -              }
 -
 -              // Aux symbol info
 -              auxs := r.Auxs(i)
 -              for j := range auxs {
 -                      a := &auxs[j]
 -                      switch a.Type() {
 -                      case goobj2.AuxFuncInfo, goobj2.AuxFuncdata, goobj2.AuxGotype:
 -                              // already handled
 -                      case goobj2.AuxDwarfInfo, goobj2.AuxDwarfLoc, goobj2.AuxDwarfRanges, goobj2.AuxDwarfLines:
 -                              // ignored for now
 -                      default:
 -                              panic("unknown aux type")
 -                      }
 -              }
 -
 -              if s.Size < int64(size) {
 -                      s.Size = int64(size)
 -              }
 -      }
 -}
 -
 -// convertRelocations takes a vector of loader.Reloc relocations and
 -// translates them into an equivalent set of sym.Reloc relocations on
 -// the symbol "dst", performing fixups along the way for ABI aliases,
 -// etc. It is assumed that the caller has pre-allocated the dst symbol
 -// relocations slice. If 'strict' is set, then this method will
 -// panic if it finds a relocation targeting a nil symbol.
 -func (l *Loader) convertRelocations(symIdx Sym, src *Relocs, dst *sym.Symbol, strict bool) {
 -      for j := range dst.R {
 -              r := src.At2(j)
 -              rs := r.Sym()
 -              sz := r.Siz()
 -              rt := r.Type()
 -              if rt == objabi.R_METHODOFF {
 -                      if l.attrReachable.Has(rs) {
 -                              rt = objabi.R_ADDROFF
 -                      } else {
 -                              sz = 0
 -                              rs = 0
 -                      }
 -              }
 -              if rt == objabi.R_WEAKADDROFF && !l.attrReachable.Has(rs) {
 -                      rs = 0
 -                      sz = 0
 -              }
 -              if rs != 0 && l.Syms[rs] != nil && l.Syms[rs].Type == sym.SABIALIAS {
 -                      rsrelocs := l.Relocs(rs)
 -                      rs = rsrelocs.At2(0).Sym()
 -              }
 -              if strict && rs != 0 && l.Syms[rs] == nil && rt != objabi.R_USETYPE {
 -                      panic("nil reloc target in convertRelocations")
 -              }
 -              dst.R[j] = sym.Reloc{
 -                      Off:  r.Off(),
 -                      Siz:  sz,
 -                      Type: rt,
 -                      Add:  r.Add(),
 -                      Sym:  l.Syms[rs],
 -              }
 -              if rv := l.RelocVariant(symIdx, j); rv != 0 {
 -                      dst.R[j].InitExt()
 -                      dst.R[j].Variant = rv
 -              }
 -      }
 -}
 -
 -// Convert external relocations to sym.Relocs on symbol dst.
 -func (l *Loader) convertExtRelocs(dst *sym.Symbol, src Sym) {
 -      if int(src) >= len(l.extRelocs) {
 -              return
 -      }
 -      extRelocs := l.extRelocs[src]
 -      if len(extRelocs) == 0 {
 -              return
 -      }
 -      if len(dst.R) != 0 {
 -              panic("bad")
 -      }
 -
 -      n := len(extRelocs)
 -      batch := l.relocBatch
 -      dst.R = batch[:n:n]
 -      l.relocBatch = batch[n:]
 -      relocs := l.Relocs(src)
 -      for i := range dst.R {
 -              er := &extRelocs[i]
 -              sr := relocs.At2(er.Idx)
 -              r := &dst.R[i]
 -              r.RelocExt = &l.relocExtBatch[0]
 -              l.relocExtBatch = l.relocExtBatch[1:]
 -              r.Off = sr.Off()
 -              r.Siz = sr.Siz()
 -              r.Type = sr.Type()
 -              r.Sym = l.Syms[l.ResolveABIAlias(sr.Sym())]
 -              r.Add = sr.Add()
 -              r.Xsym = l.Syms[er.Xsym]
 -              r.Xadd = er.Xadd
 -              if rv := l.RelocVariant(src, er.Idx); rv != 0 {
 -                      r.Variant = rv
 -              }
 -      }
 -}
 -
  // relocId is essentially a <S,R> tuple identifying the Rth
  // relocation of symbol S.
  type relocId struct {
@@@ -2296,19 -2927,19 +2296,19 @@@ func (l *Loader) UndefinedRelocTargets(
        return result
  }
  
 -// AssignTextSymbolOrder populates the Textp2 slices within each
 +// AssignTextSymbolOrder populates the Textp slices within each
  // library and compilation unit, insuring that packages are laid down
  // in dependency order (internal first, then everything else). Return value
  // is a slice of all text syms.
  func (l *Loader) AssignTextSymbolOrder(libs []*sym.Library, intlibs []bool, extsyms []Sym) []Sym {
  
 -      // Library Textp2 lists should be empty at this point.
 +      // Library Textp lists should be empty at this point.
        for _, lib := range libs {
 -              if len(lib.Textp2) != 0 {
 -                      panic("expected empty Textp2 slice for library")
 +              if len(lib.Textp) != 0 {
 +                      panic("expected empty Textp slice for library")
                }
 -              if len(lib.DupTextSyms2) != 0 {
 -                      panic("expected empty DupTextSyms2 slice for library")
 +              if len(lib.DupTextSyms) != 0 {
 +                      panic("expected empty DupTextSyms slice for library")
                }
        }
  
        // call the regular addToTextp.
        assignedToUnit := MakeBitmap(l.NSym() + 1)
  
 -      // Start off textp2 with reachable external syms.
 -      textp2 := []Sym{}
 +      // Start off textp with reachable external syms.
 +      textp := []Sym{}
        for _, sym := range extsyms {
                if !l.attrReachable.Has(sym) {
                        continue
                }
 -              textp2 = append(textp2, sym)
 +              textp = append(textp, sym)
        }
  
        // Walk through all text symbols from Go object files and append
 -      // them to their corresponding library's textp2 list.
 -      for _, o := range l.objs[1:] {
 +      // them to their corresponding library's textp list.
 +      for _, o := range l.objs[goObjStart:] {
                r := o.r
                lib := r.unit.Lib
 -              for i, n := 0, r.NSym()+r.NNonpkgdef(); i < n; i++ {
 +              for i, n := uint32(0), uint32(r.NSym()+r.NNonpkgdef()); i < n; i++ {
                        gi := l.toGlobal(r, i)
                        if !l.attrReachable.Has(gi) {
                                continue
                                // We still need to record its presence in the current
                                // package, as the trampoline pass expects packages
                                // are laid out in dependency order.
 -                              lib.DupTextSyms2 = append(lib.DupTextSyms2, sym.LoaderSym(gi))
 +                              lib.DupTextSyms = append(lib.DupTextSyms, sym.LoaderSym(gi))
                                continue // symbol in different object
                        }
                        if dupok {
 -                              lib.DupTextSyms2 = append(lib.DupTextSyms2, sym.LoaderSym(gi))
 +                              lib.DupTextSyms = append(lib.DupTextSyms, sym.LoaderSym(gi))
                                continue
                        }
  
 -                      lib.Textp2 = append(lib.Textp2, sym.LoaderSym(gi))
 +                      lib.Textp = append(lib.Textp, sym.LoaderSym(gi))
                }
        }
  
                        if intlibs[idx] != doInternal {
                                continue
                        }
 -                      lists := [2][]sym.LoaderSym{lib.Textp2, lib.DupTextSyms2}
 +                      lists := [2][]sym.LoaderSym{lib.Textp, lib.DupTextSyms}
                        for i, list := range lists {
                                for _, s := range list {
                                        sym := Sym(s)
                                        if l.attrReachable.Has(sym) && !assignedToUnit.Has(sym) {
 -                                              textp2 = append(textp2, sym)
 +                                              textp = append(textp, sym)
                                                unit := l.SymUnit(sym)
                                                if unit != nil {
 -                                                      unit.Textp2 = append(unit.Textp2, s)
 +                                                      unit.Textp = append(unit.Textp, s)
                                                        assignedToUnit.Set(sym)
                                                }
                                                // Dupok symbols may be defined in multiple packages; the
                                        }
                                }
                        }
 -                      lib.Textp2 = nil
 -                      lib.DupTextSyms2 = nil
 +                      lib.Textp = nil
 +                      lib.DupTextSyms = nil
                }
        }
  
 -      return textp2
 +      return textp
  }
  
  // ErrorReporter is a helper class for reporting errors.
@@@ -2436,7 -3067,7 +2436,7 @@@ func (l *Loader) Errorf(s Sym, format s
  // For debugging.
  func (l *Loader) Dump() {
        fmt.Println("objs")
 -      for _, obj := range l.objs {
 +      for _, obj := range l.objs[goObjStart:] {
                if obj.r != nil {
                        fmt.Println(obj.i, obj.r.unit.Lib)
                }
                if l.IsExternal(i) {
                        pi = fmt.Sprintf("<ext %d>", l.extIndex(i))
                }
 -              var s *sym.Symbol
 -              if int(i) < len(l.Syms) {
 -                      s = l.Syms[i]
 -              }
 -              if s != nil {
 -                      fmt.Println(i, s, s.Type, pi)
 -              } else {
 -                      fmt.Println(i, l.SymName(i), "<not loaded>", pi)
 -              }
 +              fmt.Println(i, l.SymName(i), l.SymType(i), pi)
        }
        fmt.Println("symsByName")
        for name, i := range l.symsByName[0] {