mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/link: hash packages after loading all symbols
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>
This commit is contained in:
parent
10f43a1f4f
commit
348a7c5397
3 changed files with 37 additions and 13 deletions
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -2130,7 +2131,7 @@ func (ctxt *Link) doelf() {
|
||||||
sort.Sort(byPkg(ctxt.Library))
|
sort.Sort(byPkg(ctxt.Library))
|
||||||
h := sha1.New()
|
h := sha1.New()
|
||||||
for _, l := range ctxt.Library {
|
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.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{}))
|
||||||
addgonote(ctxt, ".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote)
|
addgonote(ctxt, ".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote)
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ import (
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"debug/elf"
|
"debug/elf"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"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 SysArch == sys.Arch386 {
|
||||||
if (Buildmode == BuildmodeCArchive && Iself) || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE || ctxt.DynlinkingGo() {
|
if (Buildmode == BuildmodeCArchive && Iself) || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE || ctxt.DynlinkingGo() {
|
||||||
got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
|
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
|
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) {
|
func objfile(ctxt *Link, lib *Library) {
|
||||||
pkg := pathtoprefix(lib.Pkg)
|
pkg := pathtoprefix(lib.Pkg)
|
||||||
|
|
||||||
|
|
@ -720,17 +754,6 @@ func objfile(ctxt *Link, lib *Library) {
|
||||||
goto out
|
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
|
off += l
|
||||||
|
|
||||||
ldpkg(ctxt, f, pkg, atolwhex(arhdr.size), lib.File, Pkgdef)
|
ldpkg(ctxt, f, pkg, atolwhex(arhdr.size), lib.File, Pkgdef)
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,7 @@ type Library struct {
|
||||||
File string
|
File string
|
||||||
Pkg string
|
Pkg string
|
||||||
Shlib string
|
Shlib string
|
||||||
hash []byte
|
hash string
|
||||||
imports []*Library
|
imports []*Library
|
||||||
textp []*Symbol // text symbols defined in this library
|
textp []*Symbol // text symbols defined in this library
|
||||||
dupTextSyms []*Symbol // dupok text symbols defined in this library
|
dupTextSyms []*Symbol // dupok text symbols defined in this library
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue