1
0
mirror of https://github.com/golang/go synced 2024-11-12 08:50:22 -07:00

cmd/link: start file-local symbols at version 10

We're going to use the linker's symbol versions to track ABIs.
Currently, version 0 is used for global symbols and version > 0 is
used for file-local symbols. This CL reserves versions 0 to 9 for
global symbols with ABIs and uses version 10 and up for file-local
symbols. To make this clean, it also introduces a method on Symbol for
querying whether it's file-local.

For #27539.

Change-Id: Id3bc7369268f35128b14318a62e86335181a80e5
Reviewed-on: https://go-review.googlesource.com/c/146859
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
This commit is contained in:
Austin Clements 2018-10-19 17:42:11 -04:00
parent ec4ae29f52
commit 14560da7e4
7 changed files with 31 additions and 14 deletions

View File

@ -256,7 +256,7 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
// (https://sourceware.org/bugzilla/show_bug.cgi?id=18270). So // (https://sourceware.org/bugzilla/show_bug.cgi?id=18270). So
// we convert the adrp; ld64 + R_ARM64_GOTPCREL into adrp; // we convert the adrp; ld64 + R_ARM64_GOTPCREL into adrp;
// add + R_ADDRARM64. // add + R_ADDRARM64.
if !(r.Sym.Version != 0 || r.Sym.Attr.VisibilityHidden() || r.Sym.Attr.Local()) && r.Sym.Type == sym.STEXT && ctxt.DynlinkingGo() { if !(r.Sym.IsFileLocal() || r.Sym.Attr.VisibilityHidden() || r.Sym.Attr.Local()) && r.Sym.Type == sym.STEXT && ctxt.DynlinkingGo() {
if o2&0xffc00000 != 0xf9400000 { if o2&0xffc00000 != 0xf9400000 {
ld.Errorf(s, "R_ARM64_GOTPCREL against unexpected instruction %x", o2) ld.Errorf(s, "R_ARM64_GOTPCREL against unexpected instruction %x", o2)
} }

View File

@ -346,10 +346,20 @@ func lookupOrDiag(ctxt *Link, n string) *sym.Symbol {
// If the symbol does not exist, it creates it if create is true, // If the symbol does not exist, it creates it if create is true,
// or returns nil otherwise. // or returns nil otherwise.
func dwarfFuncSym(ctxt *Link, s *sym.Symbol, meta string, create bool) *sym.Symbol { func dwarfFuncSym(ctxt *Link, s *sym.Symbol, meta string, create bool) *sym.Symbol {
if create { // All function ABIs use symbol version 0 for the DWARF data.
return ctxt.Syms.Lookup(meta+s.Name, int(s.Version)) //
// TODO(austin): It may be useful to have DWARF info for ABI
// wrappers, in which case we may want these versions to
// align. Better yet, replace these name lookups with a
// general way to attach metadata to a symbol.
ver := 0
if s.IsFileLocal() {
ver = int(s.Version)
} }
return ctxt.Syms.ROLookup(meta+s.Name, int(s.Version)) if create {
return ctxt.Syms.Lookup(meta+s.Name, ver)
}
return ctxt.Syms.ROLookup(meta+s.Name, ver)
} }
func dotypedef(ctxt *Link, parent *dwarf.DWDie, name string, def *dwarf.DWDie) *dwarf.DWDie { func dotypedef(ctxt *Link, parent *dwarf.DWDie, name string, def *dwarf.DWDie) *dwarf.DWDie {
@ -853,7 +863,7 @@ func dwarfDefineGlobal(ctxt *Link, s *sym.Symbol, str string, v int64, gotype *s
} }
dv := newdie(ctxt, ctxt.compUnitByPackage[lib].dwinfo, dwarf.DW_ABRV_VARIABLE, str, int(s.Version)) dv := newdie(ctxt, ctxt.compUnitByPackage[lib].dwinfo, dwarf.DW_ABRV_VARIABLE, str, int(s.Version))
newabslocexprattr(dv, v, s) newabslocexprattr(dv, v, s)
if s.Version == 0 { if !s.IsFileLocal() {
newattr(dv, dwarf.DW_AT_external, dwarf.DW_CLS_FLAG, 1, 0) newattr(dv, dwarf.DW_AT_external, dwarf.DW_CLS_FLAG, 1, 0)
} }
dt := defgotype(ctxt, gotype) dt := defgotype(ctxt, gotype)

View File

@ -2129,7 +2129,7 @@ func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int6
if s.Attr.NotInSymbolTable() { if s.Attr.NotInSymbolTable() {
continue continue
} }
if (s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC." { if (s.Name == "" || s.Name[0] == '.') && !s.IsFileLocal() && s.Name != ".rathole" && s.Name != ".TOC." {
continue continue
} }
switch s.Type { switch s.Type {

View File

@ -704,7 +704,7 @@ func (f *peFile) writeSymbols(ctxt *Link) {
} }
} }
class := IMAGE_SYM_CLASS_EXTERNAL class := IMAGE_SYM_CLASS_EXTERNAL
if s.Version != 0 || s.Attr.VisibilityHidden() || s.Attr.Local() { if s.IsFileLocal() || s.Attr.VisibilityHidden() || s.Attr.Local() {
class = IMAGE_SYM_CLASS_STATIC class = IMAGE_SYM_CLASS_STATIC
} }
f.writeSymbol(ctxt.Out, s, value, sect, typ, uint8(class)) f.writeSymbol(ctxt.Out, s, value, sect, typ, uint8(class))

View File

@ -128,7 +128,7 @@ func putelfsym(ctxt *Link, x *sym.Symbol, s string, t SymbolType, addr int64, go
// maybe one day STB_WEAK. // maybe one day STB_WEAK.
bind := STB_GLOBAL bind := STB_GLOBAL
if x.Version != 0 || x.Attr.VisibilityHidden() || x.Attr.Local() { if x.IsFileLocal() || x.Attr.VisibilityHidden() || x.Attr.Local() {
bind = STB_LOCAL bind = STB_LOCAL
} }
@ -224,7 +224,7 @@ func putplan9sym(ctxt *Link, x *sym.Symbol, s string, typ SymbolType, addr int64
t := int(typ) t := int(typ)
switch typ { switch typ {
case TextSym, DataSym, BSSSym: case TextSym, DataSym, BSSSym:
if x.Version != 0 { if x.IsFileLocal() {
t += 'a' - 'A' t += 'a' - 'A'
} }
fallthrough fallthrough

View File

@ -51,6 +51,10 @@ type AuxSymbol struct {
elftype elf.SymType elftype elf.SymType
} }
const (
SymVerStatic = 10 // Minimum version used by static (file-local) syms
)
func (s *Symbol) String() string { func (s *Symbol) String() string {
if s.Version == 0 { if s.Version == 0 {
return s.Name return s.Name
@ -58,6 +62,10 @@ func (s *Symbol) String() string {
return fmt.Sprintf("%s<%d>", s.Name, s.Version) return fmt.Sprintf("%s<%d>", s.Name, s.Version)
} }
func (s *Symbol) IsFileLocal() bool {
return s.Version >= SymVerStatic
}
func (s *Symbol) ElfsymForReloc() int32 { func (s *Symbol) ElfsymForReloc() int32 {
// If putelfsym created a local version of this symbol, use that in all // If putelfsym created a local version of this symbol, use that in all
// relocations. // relocations.

View File

@ -40,12 +40,11 @@ type Symbols struct {
} }
func NewSymbols() *Symbols { func NewSymbols() *Symbols {
hash := make([]map[string]*Symbol, SymVerStatic)
// Preallocate about 2mb for hash of non static symbols
hash[0] = make(map[string]*Symbol, 100000)
return &Symbols{ return &Symbols{
hash: []map[string]*Symbol{ hash: hash,
// preallocate about 2mb for hash of
// non static symbols
make(map[string]*Symbol, 100000),
},
Allsym: make([]*Symbol, 0, 100000), Allsym: make([]*Symbol, 0, 100000),
} }
} }