diff --git a/src/cmd/link/internal/ld/ldelf.go b/src/cmd/link/internal/ld/ldelf.go index 1aaee1c8e5..6faa4a1918 100644 --- a/src/cmd/link/internal/ld/ldelf.go +++ b/src/cmd/link/internal/ld/ldelf.go @@ -445,7 +445,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ctxt.Logf("%5.2f ldelf %s\n", obj.Cputime(), pn) } - ctxt.Syms.IncVersion() + localSymVersion := ctxt.Syms.IncVersion() base := f.Offset() var add uint64 @@ -702,7 +702,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { } name = fmt.Sprintf("%s(%s)", pkg, sect.name) - s = ctxt.Syms.Lookup(name, ctxt.Syms.Version) + s = ctxt.Syms.Lookup(name, localSymVersion) switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) { default: @@ -741,7 +741,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { symbols = make([]*Symbol, elfobj.nsymtab) for i := 1; i < elfobj.nsymtab; i++ { - if err = readelfsym(ctxt, elfobj, i, &sym, 1); err != nil { + if err = readelfsym(ctxt, elfobj, i, &sym, 1, localSymVersion); err != nil { goto bad } symbols[i] = sym.sym @@ -903,7 +903,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol rp.Sym = nil } else { - if err = readelfsym(ctxt, elfobj, int(info>>32), &sym, 0); err != nil { + if err = readelfsym(ctxt, elfobj, int(info>>32), &sym, 0, 0); err != nil { goto bad } sym.sym = symbols[info>>32] @@ -983,7 +983,7 @@ func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) { return nil } -func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int) (err error) { +func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, localSymVersion int) (err error) { if i >= elfobj.nsymtab || i < 0 { err = fmt.Errorf("invalid elf symbol index") return err @@ -1059,7 +1059,7 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int) (er // We need to be able to look this up, // so put it in the hash table. if needSym != 0 { - s = ctxt.Syms.Lookup(sym.name, ctxt.Syms.Version) + s = ctxt.Syms.Lookup(sym.name, localSymVersion) s.Type |= obj.SHIDDEN } @@ -1070,7 +1070,7 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int) (er // 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 - s = ctxt.Syms.newsym(sym.name, ctxt.Syms.Version) + s = ctxt.Syms.newsym(sym.name, localSymVersion) s.Type |= obj.SHIDDEN } diff --git a/src/cmd/link/internal/ld/ldmacho.go b/src/cmd/link/internal/ld/ldmacho.go index ab16087440..54812b1808 100644 --- a/src/cmd/link/internal/ld/ldmacho.go +++ b/src/cmd/link/internal/ld/ldmacho.go @@ -444,7 +444,7 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { var rp *Reloc var name string - ctxt.Syms.IncVersion() + localSymVersion := ctxt.Syms.IncVersion() base := f.Offset() if _, err := io.ReadFull(f, hdr[:]); err != nil { goto bad @@ -587,7 +587,7 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { continue } name = fmt.Sprintf("%s(%s/%s)", pkg, sect.segname, sect.name) - s = ctxt.Syms.Lookup(name, ctxt.Syms.Version) + s = ctxt.Syms.Lookup(name, localSymVersion) if s.Type != 0 { err = fmt.Errorf("duplicate %s/%s", sect.segname, sect.name) goto bad @@ -634,7 +634,7 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { } v := 0 if sym.type_&N_EXT == 0 { - v = ctxt.Syms.Version + v = localSymVersion } s = ctxt.Syms.Lookup(name, v) if sym.type_&N_EXT == 0 { diff --git a/src/cmd/link/internal/ld/ldpe.go b/src/cmd/link/internal/ld/ldpe.go index a0090a160a..43d33c7b19 100644 --- a/src/cmd/link/internal/ld/ldpe.go +++ b/src/cmd/link/internal/ld/ldpe.go @@ -136,7 +136,7 @@ func ldpe(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { } var sect *PeSect - ctxt.Syms.IncVersion() + localSymVersion := ctxt.Syms.IncVersion() base := f.Offset() peobj := new(PeObj) @@ -246,7 +246,7 @@ func ldpe(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { } name = fmt.Sprintf("%s(%s)", pkg, sect.name) - s = ctxt.Syms.Lookup(name, ctxt.Syms.Version) + s = ctxt.Syms.Lookup(name, localSymVersion) switch sect.sh.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 @@ -300,7 +300,7 @@ func ldpe(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { rva := Le32(symbuf[0:]) symindex := Le32(symbuf[4:]) type_ := Le16(symbuf[8:]) - if err = readpesym(ctxt, peobj, int(symindex), &sym); err != nil { + if err = readpesym(ctxt, peobj, int(symindex), &sym, localSymVersion); err != nil { goto bad } if sym.sym == nil { @@ -371,7 +371,7 @@ func ldpe(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { } } - if err = readpesym(ctxt, peobj, i, &sym); err != nil { + if err = readpesym(ctxt, peobj, i, &sym, localSymVersion); err != nil { goto bad } @@ -475,7 +475,7 @@ func issect(s *PeSym) bool { return s.sclass == IMAGE_SYM_CLASS_STATIC && s.type_ == 0 && s.name[0] == '.' } -func readpesym(ctxt *Link, peobj *PeObj, i int, y **PeSym) (err error) { +func readpesym(ctxt *Link, peobj *PeObj, i int, y **PeSym, localSymVersion int) (err error) { if uint(i) >= peobj.npesym || i < 0 { err = fmt.Errorf("invalid pe symbol index") return err @@ -514,7 +514,7 @@ func readpesym(ctxt *Link, peobj *PeObj, i int, y **PeSym) (err error) { s = ctxt.Syms.Lookup(name, 0) case IMAGE_SYM_CLASS_NULL, IMAGE_SYM_CLASS_STATIC, IMAGE_SYM_CLASS_LABEL: - s = ctxt.Syms.Lookup(name, ctxt.Syms.Version) + s = ctxt.Syms.Lookup(name, localSymVersion) s.Attr |= AttrDuplicateOK default: diff --git a/src/cmd/link/internal/ld/objfile.go b/src/cmd/link/internal/ld/objfile.go index 0392ebd7cd..6b942083ef 100644 --- a/src/cmd/link/internal/ld/objfile.go +++ b/src/cmd/link/internal/ld/objfile.go @@ -130,16 +130,17 @@ var emptyPkg = []byte(`"".`) // objReader reads Go object files. type objReader struct { - rd *bufio.Reader - ctxt *Link - pkg string - pn string - // List of symbol references for the file being read. - dupSym *Symbol + rd *bufio.Reader + ctxt *Link + pkg string + pn string + dupSym *Symbol + localSymVersion 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 []*Symbol data []byte reloc []Reloc @@ -153,11 +154,12 @@ type objReader struct { func LoadObjFile(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { start := f.Offset() r := &objReader{ - rd: f.Reader, - pkg: pkg, - ctxt: ctxt, - pn: pn, - dupSym: &Symbol{Name: ".dup"}, + rd: f.Reader, + pkg: pkg, + ctxt: ctxt, + pn: pn, + dupSym: &Symbol{Name: ".dup"}, + localSymVersion: ctxt.Syms.IncVersion(), } r.loadObjFile() if f.Offset() != start+length { @@ -166,8 +168,6 @@ func LoadObjFile(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) } func (r *objReader) loadObjFile() { - // Increment context version, versions are used to differentiate static files in different packages - r.ctxt.Syms.IncVersion() // Magic header var buf [8]uint8 @@ -452,7 +452,7 @@ func (r *objReader) readRef() { log.Fatalf("invalid symbol version %d", v) } if v == 1 { - v = r.ctxt.Syms.Version + v = r.localSymVersion } s := r.ctxt.Syms.Lookup(name, v) r.refs = append(r.refs, s) diff --git a/src/cmd/link/internal/ld/symbols.go b/src/cmd/link/internal/ld/symbols.go index d190a8c1ca..154507ddd7 100644 --- a/src/cmd/link/internal/ld/symbols.go +++ b/src/cmd/link/internal/ld/symbols.go @@ -37,8 +37,6 @@ type Symbols struct { hash []map[string]*Symbol Allsym []*Symbol - - Version int } func (syms *Symbols) newsym(name string, v int) *Symbol { @@ -80,11 +78,7 @@ func (syms *Symbols) ROLookup(name string, v int) *Symbol { } // Allocate a new version (i.e. symbol namespace). -// -// TODO(mwhudson): This would feel more natural if it returned the new -// version (or if we dropped Symbols.Version entirely and just -// returned len(syms.hash)) -func (syms *Symbols) IncVersion() { - syms.Version++ +func (syms *Symbols) IncVersion() int { syms.hash = append(syms.hash, make(map[string]*Symbol)) + return len(syms.hash) - 1 }