From: Josh Bleecher Snyder Date: Thu, 10 Mar 2016 19:14:22 +0000 (-0800) Subject: cmd/compile: allow deduplication of long strings X-Git-Tag: go1.7beta1~1343 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=a0232ea0dddfcc0827fd4094cbf261d85f0ae8f2;p=gostls13.git cmd/compile: allow deduplication of long strings String symbols' names used to appear in the final binary. Using a string's contents as it's symbol's name was a thus a bad idea if the string's name was long. Recent improvements by crawshaw have changed that. Instead of placing long strings behind opaque names in local packages, place them in the global string package and make them content-addressable. Symbol names still occur in the object files, so use a hash to avoid needless length there. Reduces the size of cmd/go by 30k. Change-Id: Ifdbbaf47bf44352418c90ddd903d5106e48db4f1 Reviewed-on: https://go-review.googlesource.com/20524 Run-TryBot: Josh Bleecher Snyder TryBot-Result: Gobot Gobot Reviewed-by: David Crawshaw --- diff --git a/src/cmd/compile/internal/gc/obj.go b/src/cmd/compile/internal/gc/obj.go index a2c944ba9c..3c79212528 100644 --- a/src/cmd/compile/internal/gc/obj.go +++ b/src/cmd/compile/internal/gc/obj.go @@ -6,7 +6,9 @@ package gc import ( "cmd/internal/obj" + "crypto/sha256" "fmt" + "io" "strconv" ) @@ -181,27 +183,22 @@ func duintptr(s *Sym, off int, v uint64) int { return duintxx(s, off, v, Widthptr) } -var stringsym_gen int - func stringsym(s string) (hdr, data *Sym) { var symname string - var pkg *Pkg if len(s) > 100 { - // huge strings are made static to avoid long names - stringsym_gen++ - symname = fmt.Sprintf(".gostring.%d", stringsym_gen) - - pkg = localpkg + // Huge strings are hashed to avoid long names in object files. + // Indulge in some paranoia by writing the length of s, too, + // as protection against length extension attacks. + h := sha256.New() + io.WriteString(h, s) + symname = fmt.Sprintf(".gostring.%d.%x", len(s), h.Sum(nil)) } else { - // small strings get named by their contents, - // so that multiple modules using the same string - // can share it. + // Small strings get named directly by their contents. symname = strconv.Quote(s) - pkg = gostringpkg } - symhdr := Pkglookup("hdr."+symname, pkg) - symdata := Pkglookup(symname, pkg) + symhdr := Pkglookup("hdr."+symname, gostringpkg) + symdata := Pkglookup(symname, gostringpkg) // SymUniq flag indicates that data is generated already if symhdr.Flags&SymUniq != 0 {