]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: hash packages after loading all symbols
authorDavid Crawshaw <crawshaw@golang.org>
Tue, 6 Dec 2016 04:20:20 +0000 (23:20 -0500)
committerDavid Crawshaw <crawshaw@golang.org>
Tue, 6 Dec 2016 14:07:40 +0000 (14:07 +0000)
Conditioning on the plugin.Open symbol existing before loading all
symbols means sometimes some packages don't have a hash value.

Fixes #17928

Change-Id: I2722449aa58eca08a25117d3ce976f11f805b5ac
Reviewed-on: https://go-review.googlesource.com/33925
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/link/internal/ld/elf.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/link.go

index b4d5aae27a683d0a1a4490fa091010f13dfd47f4..7304b5b0d3e98e9a6d4af53d8b8b9f67b39052c2 100644 (file)
@@ -10,6 +10,7 @@ import (
        "crypto/sha1"
        "encoding/binary"
        "encoding/hex"
+       "io"
        "path/filepath"
        "sort"
        "strings"
@@ -2130,7 +2131,7 @@ func (ctxt *Link) doelf() {
                sort.Sort(byPkg(ctxt.Library))
                h := sha1.New()
                for _, l := range ctxt.Library {
-                       h.Write(l.hash)
+                       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)
index fb321905e15d7bc3c97f20fbfde551a300cd5dce..a2700d9698271c9b8ce2a478c322348450f3eac6 100644 (file)
@@ -39,6 +39,7 @@ import (
        "crypto/sha1"
        "debug/elf"
        "encoding/binary"
+       "encoding/hex"
        "fmt"
        "io"
        "io/ioutil"
@@ -603,6 +604,16 @@ func (ctxt *Link) loadlib() {
                }
        }
 
+       // If package versioning is required, generate a hash of the
+       // the packages used in the link.
+       if Buildmode == BuildmodeShared || Buildmode == BuildmodePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil {
+               for i = 0; i < len(ctxt.Library); i++ {
+                       if ctxt.Library[i].Shlib == "" {
+                               genhash(ctxt, ctxt.Library[i])
+                       }
+               }
+       }
+
        if SysArch == sys.Arch386 {
                if (Buildmode == BuildmodeCArchive && Iself) || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE || ctxt.DynlinkingGo() {
                        got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
@@ -678,6 +689,29 @@ func nextar(bp *bio.Reader, off int64, a *ArHdr) int64 {
        return arsize + SAR_HDR
 }
 
+func genhash(ctxt *Link, lib *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 arhdr ArHdr
+       l := nextar(f, int64(len(ARMAG)), &arhdr)
+       if l <= 0 {
+               Errorf(nil, "%s: short read on archive file symbol header", lib.File)
+               return
+       }
+
+       h := sha1.New()
+       if _, err := io.CopyN(h, f, atolwhex(arhdr.size)); err != nil {
+               Errorf(nil, "bad read of %s for hash generation: %v", lib.File, err)
+               return
+       }
+       lib.hash = hex.EncodeToString(h.Sum(nil))
+}
+
 func objfile(ctxt *Link, lib *Library) {
        pkg := pathtoprefix(lib.Pkg)
 
@@ -720,17 +754,6 @@ func objfile(ctxt *Link, lib *Library) {
                goto out
        }
 
-       if Buildmode == BuildmodeShared || Buildmode == BuildmodePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil {
-               before := f.Offset()
-               pkgdefBytes := make([]byte, atolwhex(arhdr.size))
-               if _, err := io.ReadFull(f, pkgdefBytes); err != nil {
-                       Errorf(nil, "%s: short read on archive file symbol header: %v", lib.File, err)
-               }
-               hash := sha1.Sum(pkgdefBytes)
-               lib.hash = hash[:]
-               f.Seek(before, 0)
-       }
-
        off += l
 
        ldpkg(ctxt, f, pkg, atolwhex(arhdr.size), lib.File, Pkgdef)
index ab7e49b51fb419a8379a0a4882ed5979af1a8fb3..ffe0873fc8684c0765f7c6d1d883b0cb536b80e8 100644 (file)
@@ -223,7 +223,7 @@ type Library struct {
        File        string
        Pkg         string
        Shlib       string
-       hash        []byte
+       hash        string
        imports     []*Library
        textp       []*Symbol // text symbols defined in this library
        dupTextSyms []*Symbol // dupok text symbols defined in this library