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:
parent
ec4ae29f52
commit
14560da7e4
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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 {
|
||||||
|
@ -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))
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user