ld.Adddynsym(ctxt, targ)
got := ctxt.Syms.Lookup(".got", 0)
- s.Type = got.Type | sym.SSUB
+ s.Type = got.Type
+ s.Attr |= sym.AttrSubSymbol
s.Outer = got
s.Sub = got.Sub
got.Sub = s
var load []uint64
for _, s := range ctxt.Syms.Allsym {
for _, r := range s.R {
- if r.Sym != nil && r.Sym.Type&sym.SMASK == sym.SXREF {
+ if r.Sym != nil && r.Sym.Type == sym.SXREF {
if off := armap[r.Sym.Name]; off != 0 && !loaded[off] {
load = append(load, off)
loaded[off] = true
continue
}
- if r.Sym != nil && ((r.Sym.Type == 0 && !r.Sym.Attr.VisibilityHidden()) || r.Sym.Type&sym.SMASK == sym.SXREF) {
+ if r.Sym != nil && ((r.Sym.Type == 0 && !r.Sym.Attr.VisibilityHidden()) || r.Sym.Type == sym.SXREF) {
// When putting the runtime but not main into a shared library
// these symbols are undefined and that's OK.
if ctxt.BuildMode == BuildModeShared {
// We need to be able to reference dynimport symbols when linking against
// shared libraries, and Solaris needs it always
- if ctxt.HeadType != objabi.Hsolaris && r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT && !ctxt.DynlinkingGo() {
+ if ctxt.HeadType != objabi.Hsolaris && r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT && !ctxt.DynlinkingGo() && !r.Sym.Attr.SubSymbol() {
if !(ctxt.Arch.Family == sys.PPC64 && ctxt.LinkMode == LinkExternal && r.Sym.Name == ".TOC.") {
Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", r.Sym.Name, r.Sym.Type, r.Sym.Type, r.Type, sym.RelocName(ctxt.Arch, r.Type))
}
func blk(ctxt *Link, syms []*sym.Symbol, addr, size int64, pad []byte) {
for i, s := range syms {
- if s.Type&sym.SSUB == 0 && s.Value >= addr {
+ if !s.Attr.SubSymbol() && s.Value >= addr {
syms = syms[i:]
break
}
eaddr := addr + size
for _, s := range syms {
- if s.Type&sym.SSUB != 0 {
+ if s.Attr.SubSymbol() {
continue
}
if s.Value >= eaddr {
// Collect data symbols by type into data.
var data [sym.SXREF][]*sym.Symbol
for _, s := range ctxt.Syms.Allsym {
- if !s.Attr.Reachable() || s.Attr.Special() {
+ if !s.Attr.Reachable() || s.Attr.Special() || s.Attr.SubSymbol() {
continue
}
if s.Type <= sym.STEXT || s.Type >= sym.SXREF {
// will not need to create new text sections, and so no need to return sect and n.
func assignAddress(ctxt *Link, sect *sym.Section, n int, s *sym.Symbol, va uint64, isTramp bool) (*sym.Section, int, uint64) {
s.Sect = sect
- if s.Type&sym.SSUB != 0 {
+ if s.Attr.SubSymbol() {
return sect, n, va
}
if s.Align != 0 {
/* type */
t := STB_GLOBAL << 4
- if s.Attr.CgoExport() && s.Type&sym.SMASK == sym.STEXT {
+ if s.Attr.CgoExport() && s.Type == sym.STEXT {
t |= STT_FUNC
} else {
t |= STT_OBJECT
t := STB_GLOBAL << 4
// TODO(mwhudson): presumably the behavior should actually be the same on both arm and 386.
- if ctxt.Arch.Family == sys.I386 && s.Attr.CgoExport() && s.Type&sym.SMASK == sym.STEXT {
+ if ctxt.Arch.Family == sys.I386 && s.Attr.CgoExport() && s.Type == sym.STEXT {
t |= STT_FUNC
- } else if ctxt.Arch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type&sym.SMASK == sym.STEXT {
+ } else if ctxt.Arch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type == sym.STEXT {
t |= STT_FUNC
} else {
t |= STT_OBJECT
any := false
for _, s := range ctxt.Syms.Allsym {
for _, r := range s.R {
- if r.Sym != nil && r.Sym.Type&sym.SMASK == sym.SXREF && r.Sym.Name != ".got" {
+ if r.Sym != nil && r.Sym.Type == sym.SXREF && r.Sym.Name != ".got" {
any = true
break
}
if (s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC." {
continue
}
- switch s.Type & sym.SMASK {
+ switch s.Type {
case sym.SCONST,
sym.SRODATA,
sym.SSYMTAB,
dynamic.Type = sym.SWINDOWS
for d := dr; d != nil; d = d.next {
for m = d.ms; m != nil; m = m.next {
- m.s.Type = sym.SWINDOWS | sym.SSUB
+ m.s.Type = sym.SWINDOWS
+ m.s.Attr |= sym.AttrSubSymbol
m.s.Sub = dynamic.Sub
dynamic.Sub = m.s
m.s.Value = dynamic.Size
s.Sub = sect.sym.Sub
sect.sym.Sub = s
- s.Type = sect.sym.Type | s.Type&^sym.SMASK | sym.SSUB
+ s.Type = sect.sym.Type
+ s.Attr |= sym.AttrSubSymbol
if !s.Attr.CgoExportDynamic() {
s.Dynimplib = "" // satisfy dynimport
}
return errorf("duplicate symbol reference: %s in both %s and %s", s.Name, s.Outer.Name, sect.sym.Name)
}
- s.Type = outer.Type | sym.SSUB
+ s.Type = outer.Type
+ s.Attr |= sym.AttrSubSymbol
s.Sub = outer.Sub
outer.Sub = s
s.Outer = outer
sectsym := sectsyms[sect]
s.Sub = sectsym.Sub
sectsym.Sub = s
- s.Type = sectsym.Type | sym.SSUB
+ s.Type = sectsym.Type
+ s.Attr |= sym.AttrSubSymbol
s.Value = int64(pesym.Value)
s.Size = 4
s.Outer = sectsym
package sym
// Attribute is a set of common symbol attributes.
-type Attribute uint16
+type Attribute int32
const (
// AttrDuplicateOK marks a symbol that can be present in multiple object
// the final executable. Only relevant when internally linking
// on an ELF platform.
AttrVisibilityHidden
+ // AttrSubSymbol mostly means that the symbol appears on the Sub list of some
+ // other symbol. Unfortunately, it's not 100% reliable; at least, it's not set
+ // correctly for the .TOC. symbol in Link.dodata. Usually the Outer field of the
+ // symbol points to the symbol whose list it is on, but that it is not set for the
+ // symbols added to .windynamic in initdynimport in pe.go.
+ //
+ // TODO(mwhudson): fix the inconsistencies noticed above.
+ //
+ // Sub lists are used when loading host objects (sections from the host object
+ // become regular linker symbols and symbols go on the Sub list of their section)
+ // and for constructing the global offset table when internally linking a dynamic
+ // executable.
+ //
+ // TOOD(mwhudson): perhaps a better name for this is AttrNonGoSymbol.
+ AttrSubSymbol
// AttrContainer is set on text symbols that are present as the .Outer for some
// other symbol.
AttrContainer
- // 16 attributes defined so far.
+ // 17 attributes defined so far.
)
func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 }
func (a Attribute) MakeTypelink() bool { return a&AttrMakeTypelink != 0 }
func (a Attribute) Shared() bool { return a&AttrShared != 0 }
func (a Attribute) VisibilityHidden() bool { return a&AttrVisibilityHidden != 0 }
+func (a Attribute) SubSymbol() bool { return a&AttrSubSymbol != 0 }
func (a Attribute) Container() bool { return a&AttrContainer != 0 }
func (a Attribute) CgoExport() bool {
SDWARFINFO
SDWARFRANGE
SDWARFLOC
- SSUB = SymKind(1 << 8)
- SMASK = SymKind(SSUB - 1)
)
// AbiSymKindToSymKind maps values read from object files (which are
ld.Adddynsym(ctxt, targ)
got := ctxt.Syms.Lookup(".got", 0)
- s.Type = got.Type | sym.SSUB
+ s.Type = got.Type
+ s.Attr |= sym.AttrSubSymbol
s.Outer = got
s.Sub = got.Sub
got.Sub = s