summaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorAlessandro Arzilli <alessandro.arzilli@gmail.com>2018-08-23 14:01:59 +0200
committerHeschi Kreinick <heschi@google.com>2018-08-28 20:56:26 +0000
commit618bfb28dc02c410659312f38cd3500352ba15ed (patch)
treeb337484c0b72f2845a88e10578999c2ef266abaa /src/cmd
parent7c7cecc1846aaaa0ce73931644fe1df2b4559e09 (diff)
downloadgo-git-618bfb28dc02c410659312f38cd3500352ba15ed.tar.gz
cmd/link: move type name mangling after deadcode elimination
Moves type name mangling after deadcode elimination. The motivation for doing this is to create a space between deadcode elimination and type name mangling where DWARF generation for types and variables can exist, to fix issue #23733. Change-Id: I9db8ecc0f4efe3df6c1e4025f02642fd452f9a39 Reviewed-on: https://go-review.googlesource.com/111236 Reviewed-by: Heschi Kreinick <heschi@google.com> Reviewed-by: Cherry Zhang <cherryyz@google.com> Run-TryBot: Heschi Kreinick <heschi@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/link/internal/ld/lib.go45
-rw-r--r--src/cmd/link/internal/ld/main.go1
-rw-r--r--src/cmd/link/internal/sym/symbols.go10
3 files changed, 30 insertions, 26 deletions
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index bfb9d9b772..1b6d5d1704 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -577,27 +577,6 @@ func (ctxt *Link) loadlib() {
}
}
- // If type. symbols are visible in the symbol table, rename them
- // using a SHA-1 prefix. This reduces binary size (the full
- // string of a type symbol can be multiple kilobytes) and removes
- // characters that upset external linkers.
- //
- // 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, and also symbols whose names
- // would not be shortened by this process.
- if typeSymbolMangling(ctxt) {
- *FlagW = true // disable DWARF generation
- for _, s := range ctxt.Syms.Allsym {
- newName := typeSymbolMangle(s.Name)
- if newName != s.Name {
- ctxt.Syms.Rename(s.Name, newName, int(s.Version))
- }
- }
- }
-
// If package versioning is required, generate a hash of the
// packages used in the link.
if ctxt.BuildMode == BuildModeShared || ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
@@ -657,23 +636,39 @@ func (ctxt *Link) loadlib() {
}
}
-// typeSymbolMangling reports whether the linker should shorten the
-// names of symbols that represent Go types.
+// mangleTypeSym shortens the names of symbols that represent Go types
+// if they are visible in the symbol table.
//
// As the names of these symbols are derived from the string of
// the type, they can run to many kilobytes long. So we shorten
// them using a SHA-1 when the name appears in the final binary.
+// This also removes characters that upset external linkers.
//
// These are the symbols that begin with the prefix 'type.' and
// contain run-time type information used by the runtime and reflect
// packages. All Go binaries contain these symbols, but only only
// those programs loaded dynamically in multiple parts need these
// symbols to have entries in the symbol table.
-func typeSymbolMangling(ctxt *Link) bool {
- return ctxt.BuildMode == BuildModeShared || ctxt.linkShared || ctxt.BuildMode == BuildModePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil
+func (ctxt *Link) mangleTypeSym() {
+ if ctxt.BuildMode != BuildModeShared && !ctxt.linkShared && ctxt.BuildMode != BuildModePlugin && ctxt.Syms.ROLookup("plugin.Open", 0) == nil {
+ return
+ }
+
+ *FlagW = true // disable DWARF generation
+ for _, s := range ctxt.Syms.Allsym {
+ newName := typeSymbolMangle(s.Name)
+ if newName != s.Name {
+ ctxt.Syms.Rename(s.Name, newName, int(s.Version), ctxt.Reachparent)
+ }
+ }
}
// typeSymbolMangle mangles the given symbol name into something shorter.
+//
+// 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.
func typeSymbolMangle(name string) string {
if !strings.HasPrefix(name, "type.") {
return name
diff --git a/src/cmd/link/internal/ld/main.go b/src/cmd/link/internal/ld/main.go
index 23462f1154..0c5ac47043 100644
--- a/src/cmd/link/internal/ld/main.go
+++ b/src/cmd/link/internal/ld/main.go
@@ -211,6 +211,7 @@ func Main(arch *sys.Arch, theArch Arch) {
if objabi.Fieldtrack_enabled != 0 {
fieldtrack(ctxt)
}
+ ctxt.mangleTypeSym()
ctxt.callgraph()
ctxt.doelf()
diff --git a/src/cmd/link/internal/sym/symbols.go b/src/cmd/link/internal/sym/symbols.go
index 98a5ae67b8..f9405db185 100644
--- a/src/cmd/link/internal/sym/symbols.go
+++ b/src/cmd/link/internal/sym/symbols.go
@@ -95,7 +95,7 @@ func (syms *Symbols) IncVersion() int {
}
// Rename renames a symbol.
-func (syms *Symbols) Rename(old, new string, v int) {
+func (syms *Symbols) Rename(old, new string, v int, reachparent map[*Symbol]*Symbol) {
s := syms.hash[v][old]
s.Name = new
if s.Extname == old {
@@ -108,8 +108,16 @@ func (syms *Symbols) Rename(old, new string, v int) {
syms.hash[v][new] = s
} else {
if s.Type == 0 {
+ dup.Attr |= s.Attr
+ if s.Attr.Reachable() && reachparent != nil {
+ reachparent[dup] = reachparent[s]
+ }
*s = *dup
} else if dup.Type == 0 {
+ s.Attr |= dup.Attr
+ if dup.Attr.Reachable() && reachparent != nil {
+ reachparent[s] = reachparent[dup]
+ }
*dup = *s
syms.hash[v][new] = s
}