]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: allow deduplication of long strings
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 10 Mar 2016 19:14:22 +0000 (11:14 -0800)
committerJosh Bleecher Snyder <josharian@gmail.com>
Mon, 14 Mar 2016 19:54:58 +0000 (19:54 +0000)
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 <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
src/cmd/compile/internal/gc/obj.go

index a2c944ba9c39314e2901f6ace70a735e76e6747e..3c79212528cd022b70460878509dd9d793fab2d7 100644 (file)
@@ -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 {