Reduces the size of LSym struct.
On 32bit: before 84 after 76
On 64bit: before 136 after 128
name old time/op new time/op delta
Template 182ms ± 3% 182ms ± 3% ~ (p=0.607 n=19+20)
Unicode 93.5ms ± 4% 94.2ms ± 3% ~ (p=0.141 n=20+19)
GoTypes 608ms ± 1% 605ms ± 2% ~ (p=0.056 n=20+20)
name old user-ns/op new user-ns/op delta
Template 249M ± 7% 249M ± 4% ~ (p=0.605 n=18+19)
Unicode 149M ±14% 151M ± 5% ~ (p=0.724 n=20+17)
GoTypes 855M ± 4% 853M ± 3% ~ (p=0.537 n=19+19)
name old alloc/op new alloc/op delta
Template 40.3MB ± 0% 40.3MB ± 0% -0.11% (p=0.000 n=19+20)
Unicode 33.8MB ± 0% 33.8MB ± 0% -0.08% (p=0.000 n=20+20)
GoTypes 119MB ± 0% 119MB ± 0% -0.10% (p=0.000 n=19+20)
name old allocs/op new allocs/op delta
Template 383k ± 0% 383k ± 0% ~ (p=0.703 n=20+20)
Unicode 317k ± 0% 317k ± 0% ~ (p=0.982 n=19+18)
GoTypes 1.14M ± 0% 1.14M ± 0% ~ (p=0.086 n=20+20)
Change-Id: Id6ba0db3ecc4503a4e9af3ed0d5884d4366e8bf9
Reviewed-on: https://go-review.googlesource.com/31870
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Run-TryBot: Shahar Kohanim <skohanim@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
func ggloblLSym(s *obj.LSym, width int32, flags int16) {
if flags&obj.LOCAL != 0 {
- s.Local = true
+ s.Set(obj.AttrLocal, true)
flags &^= obj.LOCAL
}
Ctxt.Globl(s, int64(width), int(flags))
symdata := obj.Linklookup(Ctxt, symdataname, 0)
- if !symdata.Seenglobl {
+ if !symdata.SeenGlobl() {
// string data
off := dsnameLSym(symdata, 0, s)
ggloblLSym(symdata, int32(off), obj.DUPOK|obj.RODATA|obj.LOCAL)
ptxt.From3.Offset |= obj.REFLECTMETHOD
}
if fn.Func.Pragma&Systemstack != 0 {
- ptxt.From.Sym.Cfunc = true
+ ptxt.From.Sym.Set(obj.AttrCFunc, true)
}
// Clumsy but important.
duint32(sym, 0, uint32(i)) // number of bitmaps
ls := Linksym(sym)
ls.Name = fmt.Sprintf("gclocals·%x", md5.Sum(ls.P))
- ls.Dupok = true
+ ls.Set(obj.AttrDuplicateOK, true)
sv := obj.SymVer{Name: ls.Name, Version: 0}
ls2, ok := Ctxt.Hash[sv]
if ok {
keep = true
}
}
- s.Lsym.MakeTypelink = keep
+ s.Lsym.Set(obj.AttrMakeTypelink, keep)
return s
}
p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_EXTERN
p.From.Sym = obj.Linklookup(gc.Ctxt, literal, 0)
- p.From.Sym.Local = true
+ p.From.Sym.Set(obj.AttrLocal, true)
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
case ssa.Op386MOVSSconst2, ssa.Op386MOVSDconst2:
// We only care about global data: NAME_EXTERN means a global
// symbol in the Go sense, and p.Sym.Local is true for a few
// internally defined symbols.
- if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
+ if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
// MOVW $sym, Rx becomes MOVW sym@GOT, Rx
// MOVW $sym+<off>, Rx becomes MOVW sym@GOT, Rx; ADD <off>, Rx
if p.As != AMOVW {
// MOVx sym, Ry becomes MOVW sym@GOT, R9; MOVx (R9), Ry
// MOVx Ry, sym becomes MOVW sym@GOT, R9; MOVx Ry, (R9)
// An addition may be inserted between the two MOVs if there is an offset.
- if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
- if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local {
+ if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
+ if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p)
}
source = &p.From
- } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local {
+ } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
source = &p.To
} else {
return
}
if cursym.Text.Mark&LEAF != 0 {
- cursym.Leaf = true
+ cursym.Set(obj.AttrLeaf, true)
if autosize == 0 {
break
}
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
- if ctxt.Cursym.Cfunc {
+ if ctxt.Cursym.CFunc() {
p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
p.To.Type = obj.TYPE_REG
call.To.Type = obj.TYPE_BRANCH
morestack := "runtime.morestack"
switch {
- case ctxt.Cursym.Cfunc:
+ case ctxt.Cursym.CFunc():
morestack = "runtime.morestackc"
case ctxt.Cursym.Text.From3.Offset&obj.NEEDCTXT == 0:
morestack = "runtime.morestack_noctxt"
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
- if ctxt.Cursym.Cfunc {
+ if ctxt.Cursym.CFunc() {
p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
p.To.Type = obj.TYPE_REG
call.To.Type = obj.TYPE_BRANCH
morestack := "runtime.morestack"
switch {
- case ctxt.Cursym.Cfunc:
+ case ctxt.Cursym.CFunc():
morestack = "runtime.morestackc"
case ctxt.Cursym.Text.From3.Offset&obj.NEEDCTXT == 0:
morestack = "runtime.morestack_noctxt"
s.Size = 4
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
- p.From.Sym.Local = true
+ p.From.Sym.Set(obj.AttrLocal, true)
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
s.Size = 8
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
- p.From.Sym.Local = true
+ p.From.Sym.Set(obj.AttrLocal, true)
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
// We only care about global data: NAME_EXTERN means a global
// symbol in the Go sense, and p.Sym.Local is true for a few
// internally defined symbols.
- if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
+ if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
// MOVD $sym, Rx becomes MOVD sym@GOT, Rx
// MOVD $sym+<off>, Rx becomes MOVD sym@GOT, Rx; ADD <off>, Rx
if p.As != AMOVD {
// MOVx sym, Ry becomes MOVD sym@GOT, REGTMP; MOVx (REGTMP), Ry
// MOVx Ry, sym becomes MOVD sym@GOT, REGTMP; MOVD Ry, (REGTMP)
// An addition may be inserted between the two MOVs if there is an offset.
- if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
- if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local {
+ if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
+ if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p)
}
source = &p.From
- } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local {
+ } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
source = &p.To
} else {
return
aoffset = 0xF0
}
if cursym.Text.Mark&LEAF != 0 {
- cursym.Leaf = true
+ cursym.Set(obj.AttrLeaf, true)
if ctxt.Autosize == 0 {
break
}
// An LSym is the sort of symbol that is written to an object file.
type LSym struct {
- Name string
- Type SymKind
- Version int16
- Dupok bool
- Cfunc bool
- Nosplit bool
- Leaf bool
- Seenglobl bool
- Onlist bool
+ Name string
+ Type SymKind
+ Version int16
+ Attribute
+
+ RefIdx int // Index of this symbol in the symbol reference list.
+ Args int32
+ Locals int32
+ Size int64
+ Gotype *LSym
+ Autom *Auto
+ Text *Prog
+ Pcln *Pcln
+ P []byte
+ R []Reloc
+}
+
+// Attribute is a set of symbol attributes.
+type Attribute int16
+
+const (
+ AttrDuplicateOK Attribute = 1 << iota
+ AttrCFunc
+ AttrNoSplit
+ AttrLeaf
+ AttrSeenGlobl
+ AttrOnList
// MakeTypelink means that the type should have an entry in the typelink table.
- MakeTypelink bool
+ AttrMakeTypelink
// ReflectMethod means the function may call reflect.Type.Method or
// reflect.Type.MethodByName. Matching is imprecise (as reflect.Type
// set in some cases when the reflect package is not called.
//
// Used by the linker to determine what methods can be pruned.
- ReflectMethod bool
+ AttrReflectMethod
// Local means make the symbol local even when compiling Go code to reference Go
// symbols in other shared libraries, as in this mode symbols are global by
// visible outside of the module (shared library or executable) that contains its
// definition. (When not compiling to support Go shared libraries, all symbols are
// local in this sense unless there is a cgo_export_* directive).
- Local bool
+ AttrLocal
+)
- RefIdx int // Index of this symbol in the symbol reference list.
- Args int32
- Locals int32
- Size int64
- Gotype *LSym
- Autom *Auto
- Text *Prog
- Pcln *Pcln
- P []byte
- R []Reloc
+func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 }
+func (a Attribute) MakeTypelink() bool { return a&AttrMakeTypelink != 0 }
+func (a Attribute) CFunc() bool { return a&AttrCFunc != 0 }
+func (a Attribute) NoSplit() bool { return a&AttrNoSplit != 0 }
+func (a Attribute) Leaf() bool { return a&AttrLeaf != 0 }
+func (a Attribute) SeenGlobl() bool { return a&AttrSeenGlobl != 0 }
+func (a Attribute) OnList() bool { return a&AttrOnList != 0 }
+func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 }
+func (a Attribute) Local() bool { return a&AttrLocal != 0 }
+
+func (a *Attribute) Set(flag Attribute, value bool) {
+ if value {
+ *a |= flag
+ } else {
+ *a &^= flag
+ }
}
// The compiler needs LSym to satisfy fmt.Stringer, because it stores
}
if cursym.Text.Mark&LEAF != 0 {
- cursym.Leaf = true
+ cursym.Set(obj.AttrLeaf, true)
break
}
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
- if ctxt.Cursym.Cfunc {
+ if ctxt.Cursym.CFunc() {
p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
p.To.Type = obj.TYPE_REG
p.As = AJAL
p.To.Type = obj.TYPE_BRANCH
- if ctxt.Cursym.Cfunc {
+ if ctxt.Cursym.CFunc() {
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
} else if ctxt.Cursym.Text.From3.Offset&obj.NEEDCTXT == 0 {
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0)
if s.Type != 0 {
fmt.Fprintf(ctxt.Bso, "t=%d ", s.Type)
}
- if s.Dupok {
+ if s.DuplicateOK() {
fmt.Fprintf(ctxt.Bso, "dupok ")
}
- if s.Cfunc {
+ if s.CFunc() {
fmt.Fprintf(ctxt.Bso, "cfunc ")
}
- if s.Nosplit {
+ if s.NoSplit() {
fmt.Fprintf(ctxt.Bso, "nosplit ")
}
fmt.Fprintf(ctxt.Bso, "size=%d", s.Size)
if s.Type == STEXT {
fmt.Fprintf(ctxt.Bso, " args=%#x locals=%#x", uint64(s.Args), uint64(s.Locals))
- if s.Leaf {
+ if s.Leaf() {
fmt.Fprintf(ctxt.Bso, " leaf")
}
}
w.writeInt(int64(s.Type))
w.writeRefIndex(s)
flags := int64(0)
- if s.Dupok {
+ if s.DuplicateOK() {
flags |= 1
}
- if s.Local {
+ if s.Local() {
flags |= 1 << 1
}
- if s.MakeTypelink {
+ if s.MakeTypelink() {
flags |= 1 << 2
}
w.writeInt(flags)
w.writeInt(int64(s.Args))
w.writeInt(int64(s.Locals))
- if s.Nosplit {
+ if s.NoSplit() {
w.writeInt(1)
} else {
w.writeInt(0)
}
flags = int64(0)
- if s.Leaf {
+ if s.Leaf() {
flags |= 1
}
- if s.Cfunc {
+ if s.CFunc() {
flags |= 1 << 1
}
- if s.ReflectMethod {
+ if s.ReflectMethod() {
flags |= 1 << 2
}
w.writeInt(flags)
}
dw = append(dw, dsym)
dsym.Type = SDWARFINFO
- dsym.Dupok = s.Dupok
+ dsym.Set(AttrDuplicateOK, s.DuplicateOK())
var vars dwarf.Var
var abbrev int
var offs int32
if s.Text != nil {
log.Fatalf("duplicate TEXT for %s", s.Name)
}
- if s.Onlist {
+ if s.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Onlist = true
+ s.Set(AttrOnList, true)
text = append(text, s)
flag := int(p.From3Offset())
if flag&DUPOK != 0 {
- s.Dupok = true
+ s.Set(AttrDuplicateOK, true)
}
if flag&NOSPLIT != 0 {
- s.Nosplit = true
+ s.Set(AttrNoSplit, true)
}
if flag&REFLECTMETHOD != 0 {
- s.ReflectMethod = true
+ s.Set(AttrReflectMethod, true)
}
s.Type = STEXT
s.Text = p
}
func (ctxt *Link) Globl(s *LSym, size int64, flag int) {
- if s.Seenglobl {
+ if s.SeenGlobl() {
fmt.Printf("duplicate %v\n", s)
}
- s.Seenglobl = true
- if s.Onlist {
+ s.Set(AttrSeenGlobl, true)
+ if s.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Onlist = true
+ s.Set(AttrOnList, true)
ctxt.Data = append(ctxt.Data, s)
s.Size = size
if s.Type == 0 || s.Type == SXREF {
s.Type = SBSS
}
if flag&DUPOK != 0 {
- s.Dupok = true
+ s.Set(AttrDuplicateOK, true)
}
if flag&RODATA != 0 {
s.Type = SRODATA
s.Size = 4
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
- p.From.Sym.Local = true
+ p.From.Sym.Set(obj.AttrLocal, true)
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
s.Size = 8
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
- p.From.Sym.Local = true
+ p.From.Sym.Set(obj.AttrLocal, true)
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
s.Size = 8
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
- p.From.Sym.Local = true
+ p.From.Sym.Set(obj.AttrLocal, true)
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
// We only care about global data: NAME_EXTERN means a global
// symbol in the Go sense, and p.Sym.Local is true for a few
// internally defined symbols.
- if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
+ if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
// MOVD $sym, Rx becomes MOVD sym@GOT, Rx
// MOVD $sym+<off>, Rx becomes MOVD sym@GOT, Rx; ADD <off>, Rx
if p.As != AMOVD {
// MOVx sym, Ry becomes MOVD sym@GOT, REGTMP; MOVx (REGTMP), Ry
// MOVx Ry, sym becomes MOVD sym@GOT, REGTMP; MOVx Ry, (REGTMP)
// An addition may be inserted between the two MOVs if there is an offset.
- if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
- if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local {
+ if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
+ if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p)
}
source = &p.From
- } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local {
+ } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
source = &p.To
} else {
return
}
if cursym.Text.Mark&LEAF != 0 {
- cursym.Leaf = true
+ cursym.Set(obj.AttrLeaf, true)
break
}
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
- if ctxt.Cursym.Cfunc {
+ if ctxt.Cursym.CFunc() {
p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
p.To.Type = obj.TYPE_REG
}
var morestacksym *obj.LSym
- if ctxt.Cursym.Cfunc {
+ if ctxt.Cursym.CFunc() {
morestacksym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
} else if ctxt.Cursym.Text.From3.Offset&obj.NEEDCTXT == 0 {
morestacksym = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0)
s.Size = 4
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
- p.From.Sym.Local = true
+ p.From.Sym.Set(obj.AttrLocal, true)
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
s.Size = 8
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
- p.From.Sym.Local = true
+ p.From.Sym.Set(obj.AttrLocal, true)
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
s.Size = 8
p.From.Type = obj.TYPE_MEM
p.From.Sym = s
- p.From.Sym.Local = true
+ p.From.Sym.Set(obj.AttrLocal, true)
p.From.Name = obj.NAME_EXTERN
p.From.Offset = 0
}
// We only care about global data: NAME_EXTERN means a global
// symbol in the Go sense, and p.Sym.Local is true for a few
// internally defined symbols.
- if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
+ if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
// MOVD $sym, Rx becomes MOVD sym@GOT, Rx
// MOVD $sym+<off>, Rx becomes MOVD sym@GOT, Rx; ADD <off>, Rx
if p.To.Type != obj.TYPE_REG || p.As != AMOVD {
// MOVD sym, Ry becomes MOVD sym@GOT, REGTMP; MOVD (REGTMP), Ry
// MOVD Ry, sym becomes MOVD sym@GOT, REGTMP; MOVD Ry, (REGTMP)
// An addition may be inserted between the two MOVs if there is an offset.
- if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
- if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local {
+ if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
+ if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p)
}
source = &p.From
- } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local {
+ } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
source = &p.To
} else {
return
}
if cursym.Text.Mark&LEAF != 0 {
- cursym.Leaf = true
+ cursym.Set(obj.AttrLeaf, true)
break
}
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
- if ctxt.Cursym.Cfunc {
+ if ctxt.Cursym.CFunc() {
p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
p.To.Type = obj.TYPE_REG
p.As = ABL
p.To.Type = obj.TYPE_BRANCH
- if ctxt.Cursym.Cfunc {
+ if ctxt.Cursym.CFunc() {
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0)
} else if ctxt.Cursym.Text.From3.Offset&obj.NEEDCTXT == 0 {
p.To.Sym = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0)
_64bit uintptr // size on 64bit platforms
}{
{Addr{}, 40, 64},
- {LSym{}, 84, 136},
+ {LSym{}, 76, 128},
{Prog{}, 144, 224},
}
p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_EXTERN
p.From.Sym = s
- p.From.Sym.Local = true
+ p.From.Sym.Set(obj.AttrLocal, true)
p.From.Offset = 0
}
p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_EXTERN
p.From.Sym = s
- p.From.Sym.Local = true
+ p.From.Sym.Set(obj.AttrLocal, true)
p.From.Offset = 0
}
}
// We only care about global data: NAME_EXTERN means a global
// symbol in the Go sense, and p.Sym.Local is true for a few
// internally defined symbols.
- if p.As == lea && p.From.Type == obj.TYPE_MEM && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
+ if p.As == lea && p.From.Type == obj.TYPE_MEM && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
// $LEA sym, Rx becomes $MOV $sym, Rx which will be rewritten below
p.As = mov
p.From.Type = obj.TYPE_ADDR
}
- if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
+ if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
// $MOV $sym, Rx becomes $MOV sym@GOT, Rx
// $MOV $sym+<off>, Rx becomes $MOV sym@GOT, Rx; $LEA <off>(Rx), Rx
// On 386 only, more complicated things like PUSHL $sym become $MOV sym@GOT, CX; PUSHL CX
// MOVx sym, Ry becomes $MOV sym@GOT, R15; MOVx (R15), Ry
// MOVx Ry, sym becomes $MOV sym@GOT, R15; MOVx Ry, (R15)
// An addition may be inserted between the two MOVs if there is an offset.
- if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local {
- if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local {
+ if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
+ if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p)
}
source = &p.From
- } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local {
+ } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
source = &p.To
} else {
return
// to a PLT, so make sure the GOT pointer is loaded into BX.
// RegTo2 is set on the replacement call insn to stop it being
// processed when it is in turn passed to progedit.
- if p.Mode == 64 || (p.To.Sym != nil && p.To.Sym.Local) || p.RegTo2 != 0 {
+ if p.Mode == 64 || (p.To.Sym != nil && p.To.Sym.Local()) || p.RegTo2 != 0 {
return
}
p1 := obj.Appendp(ctxt, p)
q.To.Sym = obj.Linklookup(ctxt, "__x86.get_pc_thunk."+strings.ToLower(Rconv(int(dst))), 0)
q.To.Type = obj.TYPE_MEM
q.To.Name = obj.NAME_EXTERN
- q.To.Sym.Local = true
+ q.To.Sym.Set(obj.AttrLocal, true)
r.As = p.As
r.Scond = p.Scond
r.From = p.From
p.From.Reg = REG_SP
indir_cx(ctxt, p, &p.To)
p.To.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
- if ctxt.Cursym.Cfunc {
+ if ctxt.Cursym.CFunc() {
p.To.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
} else if framesize <= obj.StackBig {
p.From.Reg = REG_AX
indir_cx(ctxt, p, &p.To)
p.To.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
- if ctxt.Cursym.Cfunc {
+ if ctxt.Cursym.CFunc() {
p.To.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
} else {
p.As = mov
indir_cx(ctxt, p, &p.From)
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
- if ctxt.Cursym.Cfunc {
+ if ctxt.Cursym.CFunc() {
p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
p.To.Type = obj.TYPE_REG
call.To.Name = obj.NAME_EXTERN
morestack := "runtime.morestack"
switch {
- case ctxt.Cursym.Cfunc:
+ case ctxt.Cursym.CFunc():
morestack = "runtime.morestackc"
case ctxt.Cursym.Text.From3Offset()&obj.NEEDCTXT == 0:
morestack = "runtime.morestack_noctxt"