]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: use fingerprint as package hash
authorCherry Zhang <cherryyz@google.com>
Mon, 1 Jun 2020 23:36:16 +0000 (19:36 -0400)
committerCherry Zhang <cherryyz@google.com>
Thu, 4 Jun 2020 16:06:33 +0000 (16:06 +0000)
Now the compiler-generated fingerprint is a hash of the export
data. We don't need to hash it ourselves in the linker. And the
linker doesn't need to read export data at all.

Fixes #33820.

Change-Id: I54bf3ebfd0f0c72aa43a352d7b2e0575dd62970d
Reviewed-on: https://go-review.googlesource.com/c/go/+/236119
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/ld/elf.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/symtab.go
src/cmd/link/internal/sym/library.go

index eaa3ffddc4899a5a94e27a52725d1ae9c1483843..b100d07e6f7356a9f2e637b95be97f633a1a4bc3 100644 (file)
@@ -12,7 +12,6 @@ import (
        "crypto/sha1"
        "encoding/binary"
        "encoding/hex"
-       "io"
        "path/filepath"
        "sort"
        "strings"
@@ -1713,7 +1712,7 @@ func (ctxt *Link) doelf() {
                sort.Sort(byPkg(ctxt.Library))
                h := sha1.New()
                for _, l := range ctxt.Library {
-                       io.WriteString(h, l.Hash)
+                       h.Write(l.Fingerprint[:])
                }
                addgonote(ctxt, ".note.go.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{}))
                addgonote(ctxt, ".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote)
index 93524f0955936bde521088e8017e00c6e740ffe4..dcb5f798c6e1f8958939c16769f5e2c3b9563fcf 100644 (file)
@@ -48,7 +48,6 @@ import (
        "debug/macho"
        "encoding/base64"
        "encoding/binary"
-       "encoding/hex"
        "fmt"
        "io"
        "io/ioutil"
@@ -785,16 +784,6 @@ func (ctxt *Link) linksetup() {
        ctxt.loader.SetAttrReachable(moduledata, true)
        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.loader.LookupOrCreateSym("_GLOBAL_OFFSET_TABLE_", 0)
@@ -919,67 +908,6 @@ func nextar(bp *bio.Reader, off int64, a *ArHdr) int64 {
        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)
 
index a448244370909c68c2c2ca7badd59e925dbd1f1f..43639393d6e4539451478c408395aa7685252de1 100644 (file)
@@ -591,13 +591,13 @@ func (ctxt *Link) symtab() []sym.SymKind {
                        s := ldr.CreateSymForUpdate("go.link.pkghashbytes."+l.Pkg, 0)
                        s.SetReachable(true)
                        s.SetType(sym.SRODATA)
-                       s.SetSize(int64(len(l.Hash)))
-                       s.SetData([]byte(l.Hash))
+                       s.SetSize(int64(len(l.Fingerprint)))
+                       s.SetData(l.Fingerprint[:])
                        str := ldr.CreateSymForUpdate("go.link.pkghash."+l.Pkg, 0)
                        str.SetReachable(true)
                        str.SetType(sym.SRODATA)
                        str.AddAddr(ctxt.Arch, s.Sym())
-                       str.AddUint(ctxt.Arch, uint64(len(l.Hash)))
+                       str.AddUint(ctxt.Arch, uint64(len(l.Fingerprint)))
                }
        }
 
@@ -698,7 +698,7 @@ func (ctxt *Link) symtab() []sym.SymKind {
                        // pkghashes[i].name
                        addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go.link.pkgname.%d", i), l.Pkg)
                        // pkghashes[i].linktimehash
-                       addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go.link.pkglinkhash.%d", i), l.Hash)
+                       addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go.link.pkglinkhash.%d", i), string(l.Fingerprint[:]))
                        // pkghashes[i].runtimehash
                        hash := ldr.Lookup("go.link.pkghash."+l.Pkg, 0)
                        pkghashes.AddAddr(ctxt.Arch, hash)
index 18e1380a68d490372e1919ed76d4c1dab16e693b..7f6e63c0200a86d581d2aae4c0722fd25fcafaa5 100644 (file)
@@ -12,7 +12,6 @@ type Library struct {
        File        string
        Pkg         string
        Shlib       string
-       Hash        string
        Fingerprint goobj2.FingerprintType
        Autolib     []goobj2.ImportedPkg
        Imports     []*Library