mirror of https://github.com/golang/go.git
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>
This commit is contained in:
parent
7c7cecc184
commit
618bfb28dc
|
|
@ -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
|
// If package versioning is required, generate a hash of the
|
||||||
// packages used in the link.
|
// packages used in the link.
|
||||||
if ctxt.BuildMode == BuildModeShared || ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
|
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
|
// mangleTypeSym shortens the names of symbols that represent Go types
|
||||||
// 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
|
// As the names of these symbols are derived from the string of
|
||||||
// the type, they can run to many kilobytes long. So we shorten
|
// 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.
|
// 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
|
// These are the symbols that begin with the prefix 'type.' and
|
||||||
// contain run-time type information used by the runtime and reflect
|
// contain run-time type information used by the runtime and reflect
|
||||||
// packages. All Go binaries contain these symbols, but only only
|
// packages. All Go binaries contain these symbols, but only only
|
||||||
// those programs loaded dynamically in multiple parts need these
|
// those programs loaded dynamically in multiple parts need these
|
||||||
// symbols to have entries in the symbol table.
|
// symbols to have entries in the symbol table.
|
||||||
func typeSymbolMangling(ctxt *Link) bool {
|
func (ctxt *Link) mangleTypeSym() {
|
||||||
return ctxt.BuildMode == BuildModeShared || ctxt.linkShared || ctxt.BuildMode == BuildModePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil
|
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.
|
// 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 {
|
func typeSymbolMangle(name string) string {
|
||||||
if !strings.HasPrefix(name, "type.") {
|
if !strings.HasPrefix(name, "type.") {
|
||||||
return name
|
return name
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,7 @@ func Main(arch *sys.Arch, theArch Arch) {
|
||||||
if objabi.Fieldtrack_enabled != 0 {
|
if objabi.Fieldtrack_enabled != 0 {
|
||||||
fieldtrack(ctxt)
|
fieldtrack(ctxt)
|
||||||
}
|
}
|
||||||
|
ctxt.mangleTypeSym()
|
||||||
ctxt.callgraph()
|
ctxt.callgraph()
|
||||||
|
|
||||||
ctxt.doelf()
|
ctxt.doelf()
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ func (syms *Symbols) IncVersion() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rename renames a symbol.
|
// 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 := syms.hash[v][old]
|
||||||
s.Name = new
|
s.Name = new
|
||||||
if s.Extname == old {
|
if s.Extname == old {
|
||||||
|
|
@ -108,8 +108,16 @@ func (syms *Symbols) Rename(old, new string, v int) {
|
||||||
syms.hash[v][new] = s
|
syms.hash[v][new] = s
|
||||||
} else {
|
} else {
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
|
dup.Attr |= s.Attr
|
||||||
|
if s.Attr.Reachable() && reachparent != nil {
|
||||||
|
reachparent[dup] = reachparent[s]
|
||||||
|
}
|
||||||
*s = *dup
|
*s = *dup
|
||||||
} else if dup.Type == 0 {
|
} else if dup.Type == 0 {
|
||||||
|
s.Attr |= dup.Attr
|
||||||
|
if dup.Attr.Reachable() && reachparent != nil {
|
||||||
|
reachparent[s] = reachparent[dup]
|
||||||
|
}
|
||||||
*dup = *s
|
*dup = *s
|
||||||
syms.hash[v][new] = s
|
syms.hash[v][new] = s
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue