]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/buildid: move and reuse duplicated HashToString code to cmd/internal/buildid...
authorMikhail Fesenko <proggga@gmail.com>
Wed, 28 Oct 2020 20:35:23 +0000 (20:35 +0000)
committerJay Conrod <jayconrod@google.com>
Wed, 28 Oct 2020 21:52:53 +0000 (21:52 +0000)
Change-Id: I1e1ac770d4aac12d7d7ec57ef95f77a3e14a678c
GitHub-Last-Rev: c01db4346eb08ffe0c1953892fb4222764048e30
GitHub-Pull-Request: golang/go#42052
Reviewed-on: https://go-review.googlesource.com/c/go/+/263418
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
Trust: Jay Conrod <jayconrod@google.com>
Trust: Michael Matloob <matloob@golang.org>

src/cmd/buildid/buildid.go
src/cmd/go/internal/work/buildid.go
src/cmd/internal/buildid/buildid.go

index 1c7b228c98710b8c84fc0c1bd311a51f1bd8231f..699d9779508f0b0bc0e1ace2832929827db1ecd0 100644 (file)
@@ -22,21 +22,6 @@ func usage() {
 
 var wflag = flag.Bool("w", false, "write build ID")
 
-// taken from cmd/go/internal/work/buildid.go
-func hashToString(h [32]byte) string {
-       const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
-       const chunks = 5
-       var dst [chunks * 4]byte
-       for i := 0; i < chunks; i++ {
-               v := uint32(h[3*i])<<16 | uint32(h[3*i+1])<<8 | uint32(h[3*i+2])
-               dst[4*i+0] = b64[(v>>18)&0x3F]
-               dst[4*i+1] = b64[(v>>12)&0x3F]
-               dst[4*i+2] = b64[(v>>6)&0x3F]
-               dst[4*i+3] = b64[v&0x3F]
-       }
-       return string(dst[:])
-}
-
 func main() {
        log.SetPrefix("buildid: ")
        log.SetFlags(0)
@@ -63,12 +48,12 @@ func main() {
                log.Fatal(err)
        }
        matches, hash, err := buildid.FindAndHash(f, id, 0)
+       f.Close()
        if err != nil {
                log.Fatal(err)
        }
-       f.Close()
 
-       newID := id[:strings.LastIndex(id, "/")] + "/" + hashToString(hash)
+       newID := id[:strings.LastIndex(id, "/")] + "/" + buildid.HashToString(hash)
        if len(newID) != len(id) {
                log.Fatalf("%s: build ID length mismatch %q vs %q", file, id, newID)
        }
index 5cd3124e54aa3a455fb89dde40022ad226dfa74e..9ef141c619a96ba3a28878f367a5ae53a33fa3a5 100644 (file)
@@ -31,7 +31,7 @@ import (
 //
 //     actionID/[.../]contentID
 //
-// where the actionID and contentID are prepared by hashToString below.
+// where the actionID and contentID are prepared by buildid.HashToString below.
 // and are found by looking for the first or last slash.
 // Usually the buildID is simply actionID/contentID, but see below for an
 // exception.
@@ -108,31 +108,6 @@ func contentID(buildID string) string {
        return buildID[strings.LastIndex(buildID, buildIDSeparator)+1:]
 }
 
-// hashToString converts the hash h to a string to be recorded
-// in package archives and binaries as part of the build ID.
-// We use the first 120 bits of the hash (5 chunks of 24 bits each) and encode
-// it in base64, resulting in a 20-byte string. Because this is only used for
-// detecting the need to rebuild installed files (not for lookups
-// in the object file cache), 120 bits are sufficient to drive the
-// probability of a false "do not need to rebuild" decision to effectively zero.
-// We embed two different hashes in archives and four in binaries,
-// so cutting to 20 bytes is a significant savings when build IDs are displayed.
-// (20*4+3 = 83 bytes compared to 64*4+3 = 259 bytes for the
-// more straightforward option of printing the entire h in base64).
-func hashToString(h [cache.HashSize]byte) string {
-       const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
-       const chunks = 5
-       var dst [chunks * 4]byte
-       for i := 0; i < chunks; i++ {
-               v := uint32(h[3*i])<<16 | uint32(h[3*i+1])<<8 | uint32(h[3*i+2])
-               dst[4*i+0] = b64[(v>>18)&0x3F]
-               dst[4*i+1] = b64[(v>>12)&0x3F]
-               dst[4*i+2] = b64[(v>>6)&0x3F]
-               dst[4*i+3] = b64[v&0x3F]
-       }
-       return string(dst[:])
-}
-
 // toolID returns the unique ID to use for the current copy of the
 // named tool (asm, compile, cover, link).
 //
@@ -404,7 +379,7 @@ func (b *Builder) fileHash(file string) string {
        if err != nil {
                return ""
        }
-       return hashToString(sum)
+       return buildid.HashToString(sum)
 }
 
 // useCache tries to satisfy the action a, which has action ID actionHash,
@@ -427,7 +402,7 @@ func (b *Builder) useCache(a *Action, actionHash cache.ActionID, target string)
        // the actionID half; if it also appeared in the input that would be like an
        // engineered 120-bit partial SHA256 collision.
        a.actionID = actionHash
-       actionID := hashToString(actionHash)
+       actionID := buildid.HashToString(actionHash)
        if a.json != nil {
                a.json.ActionID = actionID
        }
@@ -480,7 +455,7 @@ func (b *Builder) useCache(a *Action, actionHash cache.ActionID, target string)
                                // build IDs of completed actions.
                                oldBuildID := a.buildID
                                a.buildID = id[1] + buildIDSeparator + id[2]
-                               linkID := hashToString(b.linkActionID(a.triggers[0]))
+                               linkID := buildid.HashToString(b.linkActionID(a.triggers[0]))
                                if id[0] == linkID {
                                        // Best effort attempt to display output from the compile and link steps.
                                        // If it doesn't work, it doesn't work: reusing the cached binary is more
@@ -654,7 +629,7 @@ func (b *Builder) updateBuildID(a *Action, target string, rewrite bool) error {
        if err != nil {
                return err
        }
-       newID := a.buildID[:strings.LastIndex(a.buildID, buildIDSeparator)] + buildIDSeparator + hashToString(hash)
+       newID := a.buildID[:strings.LastIndex(a.buildID, buildIDSeparator)] + buildIDSeparator + buildid.HashToString(hash)
        if len(newID) != len(a.buildID) {
                return fmt.Errorf("internal error: build ID length mismatch %q vs %q", a.buildID, newID)
        }
index 1d6563cafc3ca5caf181110bb27df51ae67e4cca..1e8855d3aca7d717d2caec7d6452d08b9db9aa3a 100644 (file)
@@ -17,12 +17,8 @@ import (
 )
 
 var (
-       errBuildIDToolchain = fmt.Errorf("build ID only supported in gc toolchain")
        errBuildIDMalformed = fmt.Errorf("malformed object file")
-       errBuildIDUnknown   = fmt.Errorf("lost build ID")
-)
 
-var (
        bangArch = []byte("!<arch>")
        pkgdef   = []byte("__.PKGDEF")
        goobject = []byte("go object ")
@@ -320,3 +316,28 @@ func readRaw(name string, data []byte) (id string, err error) {
        }
        return id, nil
 }
+
+// HashToString converts the hash h to a string to be recorded
+// in package archives and binaries as part of the build ID.
+// We use the first 120 bits of the hash (5 chunks of 24 bits each) and encode
+// it in base64, resulting in a 20-byte string. Because this is only used for
+// detecting the need to rebuild installed files (not for lookups
+// in the object file cache), 120 bits are sufficient to drive the
+// probability of a false "do not need to rebuild" decision to effectively zero.
+// We embed two different hashes in archives and four in binaries,
+// so cutting to 20 bytes is a significant savings when build IDs are displayed.
+// (20*4+3 = 83 bytes compared to 64*4+3 = 259 bytes for the
+// more straightforward option of printing the entire h in base64).
+func HashToString(h [32]byte) string {
+       const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
+       const chunks = 5
+       var dst [chunks * 4]byte
+       for i := 0; i < chunks; i++ {
+               v := uint32(h[3*i])<<16 | uint32(h[3*i+1])<<8 | uint32(h[3*i+2])
+               dst[4*i+0] = b64[(v>>18)&0x3F]
+               dst[4*i+1] = b64[(v>>12)&0x3F]
+               dst[4*i+2] = b64[(v>>6)&0x3F]
+               dst[4*i+3] = b64[v&0x3F]
+       }
+       return string(dst[:])
+}