]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: shorter type symbol names
authorDavid Crawshaw <crawshaw@golang.org>
Wed, 6 Apr 2016 17:09:06 +0000 (13:09 -0400)
committerDavid Crawshaw <crawshaw@golang.org>
Mon, 18 Apr 2016 20:32:57 +0000 (20:32 +0000)
Use (part of) a SHA-1 checksum to replace type symbol names.

In typical programs this has no effect because types are not included
in the symbol table. But when dynamically linking, types are in the
table to make sure there is only one *rtype per Go type.

Eventually we may be able to get rid of all pointers to rtype values in
the binary, but probably not by 1.7. And this has a nice effect on
binary size today:

libstd.so:
before 27.4MB
after  26.2MB

For #6853.

Change-Id: I603d7f3e5baad84f59f2fd37eeb1e4ae5acfe44a
Reviewed-on: https://go-review.googlesource.com/21583
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/link/internal/ld/objfile.go

index dffb7a3d9beafe1f0a8b8626c12da7b9f7ac73f5..566c949040378d90c78f121daffaeb4da6efff89 100644 (file)
@@ -112,6 +112,8 @@ import (
        "bytes"
        "cmd/internal/bio"
        "cmd/internal/obj"
+       "crypto/sha1"
+       "encoding/base64"
        "io"
        "log"
        "strconv"
@@ -555,6 +557,28 @@ func (r *objReader) readSymName() string {
                                r.readFull(r.rdBuf[:n])
                        }
                        r.rdBuf = adjName[:0] // in case 2*n wasn't enough
+
+                       if DynlinkingGo() {
+                               // These types are included in the symbol
+                               // table when dynamically linking. To keep
+                               // binary size down, we replace the names
+                               // with SHA-1 prefixes.
+                               //
+                               // Keep the type.. prefix, which parts of the
+                               // linker (like the DWARF generator) know means
+                               // the symbol is not decodable.
+                               //
+                               // Leave type.runtime. symbols alone, because
+                               // other parts of the linker manipulates them.
+                               if strings.HasPrefix(s, "type.") && !strings.HasPrefix(s, "type.runtime.") {
+                                       hash := sha1.Sum([]byte(s))
+                                       prefix := "type."
+                                       if s[5] == '.' {
+                                               prefix = "type.."
+                                       }
+                                       s = prefix + base64.StdEncoding.EncodeToString(hash[:6])
+                               }
+                       }
                        return s
                }
                adjName = append(adjName, origName[:i]...)