No performance improvement, but possibly more readable.
Linking juju:
tip: real 0m5.470s user 0m6.131s
this: real 0m5.392s user 0m6.087s
Change-Id: I578e94fbe6c11b19d79034c33b3db31d9689d439
Reviewed-on: https://go-review.googlesource.com/20108
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
}
func Addcall(ctxt *ld.Link, s *ld.LSym, t *ld.LSym) int64 {
- s.Reachable = true
+ s.Attr |= ld.AttrReachable
i := s.Size
s.Size += 4
ld.Symgrow(ctxt, s, s.Size)
// an init function
return
}
- addmoduledata.Reachable = true
+ addmoduledata.Attr |= ld.AttrReachable
initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0)
initfunc.Type = obj.STEXT
- initfunc.Local = true
- initfunc.Reachable = true
+ initfunc.Attr |= ld.AttrLocal
+ initfunc.Attr |= ld.AttrReachable
o := func(op ...uint8) {
for _, op1 := range op {
ld.Adduint8(ld.Ctxt, initfunc, op1)
}
ld.Ctxt.Etextp = initfunc
initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0)
- initarray_entry.Reachable = true
- initarray_entry.Local = true
+ initarray_entry.Attr |= ld.AttrReachable
+ initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Type = obj.SINITARR
ld.Addaddr(ld.Ctxt, initarray_entry, initfunc)
}
// an init function
return
}
- addmoduledata.Reachable = true
+ addmoduledata.Attr |= ld.AttrReachable
initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0)
initfunc.Type = obj.STEXT
- initfunc.Local = true
- initfunc.Reachable = true
+ initfunc.Attr |= ld.AttrLocal
+ initfunc.Attr |= ld.AttrReachable
o := func(op uint32) {
ld.Adduint32(ld.Ctxt, initfunc, op)
}
}
ld.Ctxt.Etextp = initfunc
initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0)
- initarray_entry.Reachable = true
- initarray_entry.Local = true
+ initarray_entry.Attr |= ld.AttrReachable
+ initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Type = obj.SINITARR
ld.Addaddr(ld.Ctxt, initarray_entry, initfunc)
}
r.Type = int32(typ)
r.Add = int64(sym.Got) - 8
- plt.Reachable = true
+ plt.Attr |= ld.AttrReachable
plt.Size += 4
ld.Symgrow(ctxt, plt, plt.Size)
// an init function
return
}
- addmoduledata.Reachable = true
+ addmoduledata.Attr |= ld.AttrReachable
initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0)
initfunc.Type = obj.STEXT
- initfunc.Local = true
- initfunc.Reachable = true
+ initfunc.Attr |= ld.AttrLocal
+ initfunc.Attr |= ld.AttrReachable
o := func(op uint32) {
ld.Adduint32(ld.Ctxt, initfunc, op)
}
}
ld.Ctxt.Etextp = initfunc
initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0)
- initarray_entry.Reachable = true
- initarray_entry.Local = true
+ initarray_entry.Attr |= ld.AttrReachable
+ initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Type = obj.SINITARR
ld.Addaddr(ld.Ctxt, initarray_entry, initfunc)
}
// (https://sourceware.org/bugzilla/show_bug.cgi?id=18270). So
// we convert the adrp; ld64 + R_ARM64_GOTPCREL into adrp;
// add + R_ADDRARM64.
- if !(r.Sym.Version != 0 || (r.Sym.Type&obj.SHIDDEN != 0) || r.Sym.Local) && r.Sym.Type == obj.STEXT && ld.DynlinkingGo() {
+ if !(r.Sym.Version != 0 || (r.Sym.Type&obj.SHIDDEN != 0) || r.Sym.Attr.Local()) && r.Sym.Type == obj.STEXT && ld.DynlinkingGo() {
if o2&0xffc00000 != 0xf9400000 {
ld.Ctxt.Diag("R_ARM64_GOTPCREL against unexpected instruction %x", o2)
}
if s.Type == 0 {
s.Type = obj.SDATA
}
- s.Reachable = true
+ s.Attr |= AttrReachable
if s.Size < off+wid {
s.Size = off + wid
Symgrow(ctxt, s, s.Size)
if s.Type == 0 {
s.Type = obj.SDATA
}
- s.Reachable = true
+ s.Attr |= AttrReachable
i := s.Size
s.Size += int64(ctxt.Arch.Ptrsize)
Symgrow(ctxt, s, s.Size)
if s.Type == 0 {
s.Type = obj.SDATA
}
- s.Reachable = true
+ s.Attr |= AttrReachable
i := s.Size
s.Size += 4
Symgrow(ctxt, s, s.Size)
if s.Type == 0 {
s.Type = obj.SDATA
}
- s.Reachable = true
+ s.Attr |= AttrReachable
if off+int64(ctxt.Arch.Ptrsize) > s.Size {
s.Size = off + int64(ctxt.Arch.Ptrsize)
Symgrow(ctxt, s, s.Size)
if s.Type == 0 {
s.Type = obj.SDATA
}
- s.Reachable = true
+ s.Attr |= AttrReachable
i := s.Size
s.Size += int64(ctxt.Arch.Ptrsize)
Symgrow(ctxt, s, s.Size)
if s.Type == 0 {
s.Type = obj.SDATA
}
- s.Reachable = true
+ s.Attr |= AttrReachable
i := s.Size
s.Size += 4
Symgrow(ctxt, s, s.Size)
Diag("unhandled relocation for %s (type %d rtype %d)", r.Sym.Name, r.Sym.Type, r.Type)
}
}
- if r.Sym != nil && r.Sym.Type != obj.STLSBSS && !r.Sym.Reachable {
+ if r.Sym != nil && r.Sym.Type != obj.STLSBSS && !r.Sym.Attr.Reachable() {
Diag("unreachable sym in relocation: %s %s", s.Name, r.Sym.Name)
}
if targ == nil {
continue
}
- if !targ.Reachable {
+ if !targ.Attr.Reachable() {
Diag("internal inconsistency: dynamic symbol %s is not reachable.", targ.Name)
}
if r.Sym.Plt == -2 && r.Sym.Got != -2 { // make dynimport JMP table for PE object files.
for ri := 0; ri < len(s.R); ri++ {
r = &s.R[ri]
if r.Sym != nil && r.Sym.Type == obj.SDYNIMPORT || r.Type >= 256 {
- if r.Sym != nil && !r.Sym.Reachable {
+ if r.Sym != nil && !r.Sym.Attr.Reachable() {
Diag("internal inconsistency: dynamic symbol %s is not reachable.", r.Sym.Name)
}
Thearch.Adddynrel(s, r)
var sym *LSym
for sym = Ctxt.Textp; sym != nil; sym = sym.Next {
- if !sym.Reachable {
+ if !sym.Attr.Reachable() {
continue
}
if sym.Value >= addr {
eaddr := addr + size
var q []byte
for ; sym != nil; sym = sym.Next {
- if !sym.Reachable {
+ if !sym.Attr.Reachable() {
continue
}
if sym.Value >= eaddr {
s := Linklookup(Ctxt, name, 0)
s.Size = 0
- s.Dupok = 1
- reachable := s.Reachable
+ s.Attr |= AttrDuplicateOK
+ reachable := s.Attr.Reachable()
Addaddr(Ctxt, s, sp)
adduintxx(Ctxt, s, uint64(len(value)), Thearch.Ptrsize)
// addstring, addaddr, etc., mark the symbols as reachable.
// In this case that is not necessarily true, so stick to what
// we know before entering this function.
- s.Reachable = reachable
+ s.Attr.Set(AttrReachable, reachable)
strdata = append(strdata, s)
- sp.Reachable = reachable
+ sp.Attr.Set(AttrReachable, reachable)
}
func checkstrdata() {
if s.Type == 0 {
s.Type = obj.SNOPTRDATA
}
- s.Reachable = true
+ s.Attr |= AttrReachable
r := int32(s.Size)
n := len(str) + 1
if s.Name == ".shstrtab" {
if sym.Type != obj.Sxxx {
Diag("duplicate symname in addgostring: %s", symname)
}
- sym.Reachable = true
- sym.Local = true
+ sym.Attr |= AttrReachable
+ sym.Attr |= AttrLocal
sym.Type = obj.SRODATA
sym.Size = int64(len(str))
sym.P = []byte(str)
sp := Linklookup(Ctxt, p, 0)
sp.Type = obj.SINITARR
sp.Size = 0
- sp.Dupok = 1
+ sp.Attr |= AttrDuplicateOK
Addaddr(Ctxt, sp, s)
}
datap = nil
for _, s := range Ctxt.Allsym {
- if !s.Reachable || s.Special != 0 {
+ if !s.Attr.Reachable() || s.Attr.Special() {
continue
}
if obj.STEXT < s.Type && s.Type < obj.SXREF {
- if s.Onlist != 0 {
+ if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Onlist = 1
+ s.Attr |= AttrOnList
if last == nil {
datap = s
} else {
}
sym := Linklookup(Ctxt, "go.buildid", 0)
- sym.Reachable = true
+ sym.Attr |= AttrReachable
// The \xff is invalid UTF-8, meant to make it less likely
// to find one of these accidentally.
data := "\xff Go build ID: " + strconv.Quote(buildid) + "\n \xff"
xdefine("runtime.etypelink", obj.SRODATA, int64(typelink.Vaddr+typelink.Length))
sym := Linklookup(Ctxt, "runtime.gcdata", 0)
- sym.Local = true
+ sym.Attr |= AttrLocal
xdefine("runtime.egcdata", obj.SRODATA, Symaddr(sym)+sym.Size)
Linklookup(Ctxt, "runtime.egcdata", 0).Sect = sym.Sect
sym = Linklookup(Ctxt, "runtime.gcbss", 0)
- sym.Local = true
+ sym.Attr |= AttrLocal
xdefine("runtime.egcbss", obj.SRODATA, Symaddr(sym)+sym.Size)
Linklookup(Ctxt, "runtime.egcbss", 0).Sect = sym.Sect
sect = addmachodwarfsect(sect, ".debug_info")
infosym = Linklookup(Ctxt, ".debug_info", 0)
- infosym.Hidden = true
+ infosym.Attr |= AttrHidden
abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0)
- abbrevsym.Hidden = true
+ abbrevsym.Attr |= AttrHidden
linesym = Linklookup(Ctxt, ".debug_line", 0)
- linesym.Hidden = true
+ linesym.Attr |= AttrHidden
framesym = Linklookup(Ctxt, ".debug_frame", 0)
- framesym.Hidden = true
+ framesym.Attr |= AttrHidden
}
}
}
infosym = Linklookup(Ctxt, ".debug_info", 0)
- infosym.Hidden = true
+ infosym.Attr |= AttrHidden
abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0)
- abbrevsym.Hidden = true
+ abbrevsym.Attr |= AttrHidden
linesym = Linklookup(Ctxt, ".debug_line", 0)
- linesym.Hidden = true
+ linesym.Attr |= AttrHidden
framesym = Linklookup(Ctxt, ".debug_frame", 0)
- framesym.Hidden = true
+ framesym.Attr |= AttrHidden
}
}
nsym := Nelfsym
s := Linklookup(Ctxt, ".hash", 0)
s.Type = obj.SELFROSECT
- s.Reachable = true
+ s.Attr |= AttrReachable
i := nsym
nbucket := 1
sect.Reloff = uint64(Cpos())
var sym *LSym
for sym = first; sym != nil; sym = sym.Next {
- if !sym.Reachable {
+ if !sym.Attr.Reachable() {
continue
}
if uint64(sym.Value) >= sect.Vaddr {
var r *Reloc
var ri int
for ; sym != nil; sym = sym.Next {
- if !sym.Reachable {
+ if !sym.Attr.Reachable() {
continue
}
if sym.Value >= int64(eaddr) {
func addgonote(sectionName string, tag uint32, desc []byte) {
s := Linklookup(Ctxt, sectionName, 0)
- s.Reachable = true
+ s.Attr |= AttrReachable
s.Type = obj.SELFROSECT
// namesz
Adduint32(Ctxt, s, uint32(len(ELF_NOTE_GO_NAME)))
shstrtab := Linklookup(Ctxt, ".shstrtab", 0)
shstrtab.Type = obj.SELFROSECT
- shstrtab.Reachable = true
+ shstrtab.Attr |= AttrReachable
Addstring(shstrtab, "")
Addstring(shstrtab, ".text")
s := Linklookup(Ctxt, ".dynsym", 0)
s.Type = obj.SELFROSECT
- s.Reachable = true
+ s.Attr |= AttrReachable
switch Thearch.Thechar {
case '0', '6', '7', '9':
s.Size += ELF64SYMSIZE
s = Linklookup(Ctxt, ".dynstr", 0)
s.Type = obj.SELFROSECT
- s.Reachable = true
+ s.Attr |= AttrReachable
if s.Size == 0 {
Addstring(s, "")
}
default:
s = Linklookup(Ctxt, ".rel", 0)
}
- s.Reachable = true
+ s.Attr |= AttrReachable
s.Type = obj.SELFROSECT
/* global offset table */
s = Linklookup(Ctxt, ".got", 0)
- s.Reachable = true
+ s.Attr |= AttrReachable
s.Type = obj.SELFGOT // writable
/* ppc64 glink resolver */
if Thearch.Thechar == '9' {
s := Linklookup(Ctxt, ".glink", 0)
- s.Reachable = true
+ s.Attr |= AttrReachable
s.Type = obj.SELFRXSECT
}
/* hash */
s = Linklookup(Ctxt, ".hash", 0)
- s.Reachable = true
+ s.Attr |= AttrReachable
s.Type = obj.SELFROSECT
s = Linklookup(Ctxt, ".got.plt", 0)
- s.Reachable = true
+ s.Attr |= AttrReachable
s.Type = obj.SELFSECT // writable
s = Linklookup(Ctxt, ".plt", 0)
- s.Reachable = true
+ s.Attr |= AttrReachable
if Thearch.Thechar == '9' {
// In the ppc64 ABI, .plt is a data section
// written by the dynamic linker.
default:
s = Linklookup(Ctxt, ".rel.plt", 0)
}
- s.Reachable = true
+ s.Attr |= AttrReachable
s.Type = obj.SELFROSECT
s = Linklookup(Ctxt, ".gnu.version", 0)
- s.Reachable = true
+ s.Attr |= AttrReachable
s.Type = obj.SELFROSECT
s = Linklookup(Ctxt, ".gnu.version_r", 0)
- s.Reachable = true
+ s.Attr |= AttrReachable
s.Type = obj.SELFROSECT
/* define dynamic elf table */
s = Linklookup(Ctxt, ".dynamic", 0)
- s.Reachable = true
+ s.Attr |= AttrReachable
s.Type = obj.SELFSECT // writable
/*
// The go.link.abihashbytes symbol will be pointed at the appropriate
// part of the .note.go.abihash section in data.go:func address().
s := Linklookup(Ctxt, "go.link.abihashbytes", 0)
- s.Local = true
+ s.Attr |= AttrLocal
s.Type = obj.SRODATA
- s.Special = 1
- s.Reachable = true
+ s.Attr |= AttrSpecial
+ s.Attr |= AttrReachable
s.Size = int64(sha1.Size)
sort.Sort(byPkg(Ctxt.Library))
/* type */
t := STB_GLOBAL << 4
- if s.Cgoexport != 0 && s.Type&obj.SMASK == obj.STEXT {
+ if s.Attr.CgoExport() && s.Type&obj.SMASK == obj.STEXT {
t |= STT_FUNC
} else {
t |= STT_OBJECT
/* size of object */
Adduint64(ctxt, d, uint64(s.Size))
- if Thearch.Thechar == '6' && s.Cgoexport&CgoExportDynamic == 0 && s.Dynimplib != "" && !seenlib[s.Dynimplib] {
+ if Thearch.Thechar == '6' && !s.Attr.CgoExportDynamic() && s.Dynimplib != "" && !seenlib[s.Dynimplib] {
Elfwritedynent(Linklookup(ctxt, ".dynamic", 0), DT_NEEDED, uint64(Addstring(Linklookup(ctxt, ".dynstr", 0), s.Dynimplib)))
}
} else {
t := STB_GLOBAL << 4
// TODO(mwhudson): presumably the behaviour should actually be the same on both arm and 386.
- if Thearch.Thechar == '8' && s.Cgoexport != 0 && s.Type&obj.SMASK == obj.STEXT {
+ if Thearch.Thechar == '8' && s.Attr.CgoExport() && s.Type&obj.SMASK == obj.STEXT {
t |= STT_FUNC
- } else if Thearch.Thechar == '5' && s.Cgoexport&CgoExportDynamic != 0 && s.Type&obj.SMASK == obj.STEXT {
+ } else if Thearch.Thechar == '5' && s.Attr.CgoExportDynamic() && s.Type&obj.SMASK == obj.STEXT {
t |= STT_FUNC
} else {
t |= STT_OBJECT
s.Type = 0
}
- if s.Cgoexport == 0 {
+ if !s.Attr.CgoExport() {
s.Extname = remote
dynexp = append(dynexp, s)
} else if s.Extname != remote {
}
if f[0] == "cgo_export_static" {
- s.Cgoexport |= CgoExportStatic
+ s.Attr |= AttrCgoExportStatic
} else {
- s.Cgoexport |= CgoExportDynamic
+ s.Attr |= AttrCgoExportDynamic
}
if local != f[1] {
}
var emarkq *LSym
func mark1(s *LSym, parent *LSym) {
- if s == nil || s.Reachable {
+ if s == nil || s.Attr.Reachable() {
return
}
if strings.HasPrefix(s.Name, "go.weak.") {
return
}
- s.Reachable = true
+ s.Attr |= AttrReachable
s.Reachparent = parent
if markq == nil {
markq = s
// keep each beginning with 'typelink.' if the symbol it points at is being kept.
for _, s := range Ctxt.Allsym {
if strings.HasPrefix(s.Name, "go.typelink.") {
- s.Reachable = len(s.R) == 1 && s.R[0].Sym.Reachable
+ s.Attr.Set(AttrReachable, len(s.R) == 1 && s.R[0].Sym.Attr.Reachable())
}
}
var last *LSym
for s := Ctxt.Textp; s != nil; s = s.Next {
- if !s.Reachable {
+ if !s.Attr.Reachable() {
continue
}
for _, s := range Ctxt.Allsym {
if strings.HasPrefix(s.Name, "go.weak.") {
- s.Special = 1 // do not lay out in data segment
- s.Reachable = true
- s.Hidden = true
+ s.Attr |= AttrSpecial // do not lay out in data segment
+ s.Attr |= AttrReachable
+ s.Attr |= AttrHidden
}
}
var buf bytes.Buffer
for _, s := range Ctxt.Allsym {
if strings.HasPrefix(s.Name, "go.track.") {
- s.Special = 1 // do not lay out in data segment
- s.Hidden = true
- if s.Reachable {
+ s.Attr |= AttrSpecial // do not lay out in data segment
+ s.Attr |= AttrHidden
+ if s.Attr.Reachable() {
buf.WriteString(s.Name[9:])
for p := s.Reachparent; p != nil; p = p.Reachparent {
buf.WriteString("\t")
return
}
s := Linklookup(Ctxt, tracksym, 0)
- if !s.Reachable {
+ if !s.Attr.Reachable() {
return
}
addstrdata(tracksym, buf.String())
for _, s := range Ctxt.Allsym {
if strings.HasPrefix(s.Name, "go.weak.") {
t := Linkrlookup(Ctxt, s.Name[8:], int(s.Version))
- if t != nil && t.Type != 0 && t.Reachable {
+ if t != nil && t.Type != 0 && t.Attr.Reachable() {
s.Value = t.Value
s.Type = t.Type
s.Outer = t
s = sym.sym
if s.Outer != nil {
- if s.Dupok != 0 {
+ if s.Attr.DuplicateOK() {
continue
}
Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name)
s.Sub = sect.sym.Sub
sect.sym.Sub = s
s.Type = sect.sym.Type | s.Type&^obj.SMASK | obj.SSUB
- if s.Cgoexport&CgoExportDynamic == 0 {
+ if !s.Attr.CgoExportDynamic() {
s.Dynimplib = "" // satisfy dynimport
}
s.Value = int64(sym.value)
s.Size = int64(sym.size)
s.Outer = sect.sym
if sect.sym.Type == obj.STEXT {
- if s.External != 0 && s.Dupok == 0 {
+ if s.Attr.External() && !s.Attr.DuplicateOK() {
Diag("%s: duplicate definition of %s", pn, s.Name)
}
- s.External = 1
+ s.Attr |= AttrExternal
}
if elfobj.machine == ElfMachPower64 {
s.Sub = listsort(s.Sub, valuecmp, listsubp)
}
if s.Type == obj.STEXT {
- if s.Onlist != 0 {
+ if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Onlist = 1
+ s.Attr |= AttrOnList
if Ctxt.Etextp != nil {
Ctxt.Etextp.Next = s
} else {
}
Ctxt.Etextp = s
for s = s.Sub; s != nil; s = s.Sub {
- if s.Onlist != 0 {
+ if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Onlist = 1
+ s.Attr |= AttrOnList
Ctxt.Etextp.Next = s
Ctxt.Etextp = s
}
// comment #5 for details.
if s != nil && sym.other == 2 {
s.Type |= obj.SHIDDEN
- s.Dupok = 1
+ s.Attr |= AttrDuplicateOK
}
}
}
s = Linklookup(Ctxt, name, v)
if sym.type_&N_EXT == 0 {
- s.Dupok = 1
+ s.Attr |= AttrDuplicateOK
}
sym.sym = s
if sym.sectnum == 0 { // undefined
}
if s.Outer != nil {
- if s.Dupok != 0 {
+ if s.Attr.DuplicateOK() {
continue
}
Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name)
outer.Sub = s
s.Outer = outer
s.Value = int64(sym.value - sect.addr)
- if s.Cgoexport&CgoExportDynamic == 0 {
+ if !s.Attr.CgoExportDynamic() {
s.Dynimplib = "" // satisfy dynimport
}
if outer.Type == obj.STEXT {
- if s.External != 0 && s.Dupok == 0 {
+ if s.Attr.External() && !s.Attr.DuplicateOK() {
Diag("%s: duplicate definition of %s", pn, s.Name)
}
- s.External = 1
+ s.Attr |= AttrExternal
}
sym.sym = s
}
if s.Type == obj.STEXT {
- if s.Onlist != 0 {
+ if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Onlist = 1
+ s.Attr |= AttrOnList
if Ctxt.Etextp != nil {
Ctxt.Etextp.Next = s
} else {
}
Ctxt.Etextp = s
for s1 = s.Sub; s1 != nil; s1 = s1.Sub {
- if s1.Onlist != 0 {
+ if s1.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s1.Name)
}
- s1.Onlist = 1
+ s1.Attr |= AttrOnList
Ctxt.Etextp.Next = s1
Ctxt.Etextp = s1
}
}
if s.Outer != nil {
- if s.Dupok != 0 {
+ if s.Attr.DuplicateOK() {
continue
}
Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name)
s.Size = 4
s.Outer = sect.sym
if sect.sym.Type == obj.STEXT {
- if s.External != 0 && s.Dupok == 0 {
+ if s.Attr.External() && !s.Attr.DuplicateOK() {
Diag("%s: duplicate definition of %s", pn, s.Name)
}
- s.External = 1
+ s.Attr |= AttrExternal
}
}
s.Sub = listsort(s.Sub, valuecmp, listsubp)
}
if s.Type == obj.STEXT {
- if s.Onlist != 0 {
+ if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Onlist = 1
+ s.Attr |= AttrOnList
if Ctxt.Etextp != nil {
Ctxt.Etextp.Next = s
} else {
}
Ctxt.Etextp = s
for s = s.Sub; s != nil; s = s.Sub {
- if s.Onlist != 0 {
+ if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Onlist = 1
+ s.Attr |= AttrOnList
Ctxt.Etextp.Next = s
Ctxt.Etextp = s
}
case IMAGE_SYM_CLASS_NULL, IMAGE_SYM_CLASS_STATIC, IMAGE_SYM_CLASS_LABEL:
s = Linklookup(Ctxt, name, Ctxt.Version)
- s.Dupok = 1
+ s.Attr |= AttrDuplicateOK
default:
err = fmt.Errorf("%s: invalid symbol binding %d", sym.name, sym.sclass)
liveness int64
)
-// for dynexport field of LSym
-const (
- CgoExportDynamic = 1 << 0
- CgoExportStatic = 1 << 1
-)
-
var (
Segtext Segment
Segrodata Segment
switch Buildmode {
case BuildmodeCShared:
s := Linklookup(Ctxt, "runtime.islibrary", 0)
- s.Dupok = 1
+ s.Attr |= AttrDuplicateOK
Adduint8(Ctxt, s, 1)
case BuildmodeCArchive:
s := Linklookup(Ctxt, "runtime.isarchive", 0)
- s.Dupok = 1
+ s.Attr |= AttrDuplicateOK
Adduint8(Ctxt, s, 1)
}
// cgo_import_static and cgo_import_dynamic,
// then we want to make it cgo_import_dynamic
// now.
- if s.Extname != "" && s.Dynimplib != "" && s.Cgoexport == 0 {
+ if s.Extname != "" && s.Dynimplib != "" && !s.Attr.CgoExport() {
s.Type = obj.SDYNIMPORT
} else {
s.Type = 0
} else if tlsg.Type != obj.SDYNIMPORT {
Diag("internal error: runtime declared tlsg variable %d", tlsg.Type)
}
- tlsg.Reachable = true
+ tlsg.Attr |= AttrReachable
Ctxt.Tlsg = tlsg
moduledata := Linklookup(Ctxt, "runtime.firstmoduledata", 0)
// If OTOH the module does not contain the runtime package,
// create a local symbol for the moduledata.
moduledata = Linklookup(Ctxt, "local.moduledata", 0)
- moduledata.Local = true
+ moduledata.Attr |= AttrLocal
}
// In all cases way we mark the moduledata as noptrdata to hide it from
// the GC.
moduledata.Type = obj.SNOPTRDATA
- moduledata.Reachable = true
+ moduledata.Attr |= AttrReachable
Ctxt.Moduledata = moduledata
// Now that we know the link mode, trim the dynexp list.
- x := CgoExportDynamic
+ x := AttrCgoExportDynamic
if Linkmode == LinkExternal {
- x = CgoExportStatic
+ x = AttrCgoExportStatic
}
w := 0
for i := 0; i < len(dynexp); i++ {
- if int(dynexp[i].Cgoexport)&x != 0 {
+ if dynexp[i].Attr&x != 0 {
dynexp[w] = dynexp[i]
w++
}
continue
}
- if s.Nosplit != 0 {
+ if s.Attr.NoSplit() {
Ctxt.Cursym = s
ch.sym = s
stkcheck(&ch, 0)
}
for s := Ctxt.Textp; s != nil; s = s.Next {
- if s.Nosplit == 0 {
+ if !s.Attr.NoSplit() {
Ctxt.Cursym = s
ch.sym = s
stkcheck(&ch, 0)
// function at top of safe zone once.
top := limit == obj.StackLimit-callsize()
if top {
- if s.Stkcheck != 0 {
+ if s.Attr.StackCheck() {
return 0
}
- s.Stkcheck = 1
+ s.Attr |= AttrStackCheck
}
if depth > 100 {
return -1
}
- if s.External != 0 || s.Pcln == nil {
+ if s.Attr.External() || s.Pcln == nil {
// external function.
// should never be called directly.
// only diagnose the direct caller.
var ch Chain
ch.up = up
- if s.Nosplit == 0 {
+ if !s.Attr.NoSplit() {
// Ensure we have enough stack to call morestack.
ch.limit = limit - callsize()
ch.sym = morestack
if ch.sym != nil {
name = ch.sym.Name
- if ch.sym.Nosplit != 0 {
+ if ch.sym.Attr.NoSplit() {
name += " (nosplit)"
}
} else {
if ch.up == nil {
// top of chain. ch->sym != nil.
- if ch.sym.Nosplit != 0 {
+ if ch.sym.Attr.NoSplit() {
fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name)
} else {
fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name)
}
for _, s := range Ctxt.Allsym {
- if s.Hidden || ((s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC.") {
+ if s.Attr.Hidden() {
+ continue
+ }
+ if (s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC." {
continue
}
switch s.Type & obj.SMASK {
obj.SRODATARELRO,
obj.STYPELINK,
obj.SWINDOWS:
- if !s.Reachable {
+ if !s.Attr.Reachable() {
continue
}
put(s, s.Name, 'D', Symaddr(s), s.Size, int(s.Version), s.Gotype)
case obj.SBSS, obj.SNOPTRBSS:
- if !s.Reachable {
+ if !s.Attr.Reachable() {
continue
}
if len(s.P) > 0 {
- Diag("%s should not be bss (size=%d type=%d special=%d)", s.Name, int(len(s.P)), s.Type, s.Special)
+ Diag("%s should not be bss (size=%d type=%d special=%v)", s.Name, int(len(s.P)), s.Type, s.Attr.Special())
}
put(s, s.Name, 'B', Symaddr(s), s.Size, int(s.Version), s.Gotype)
}
case obj.SDYNIMPORT:
- if !s.Reachable {
+ if !s.Attr.Reachable() {
continue
}
put(s, s.Extname, 'U', 0, 0, int(s.Version), nil)
}
func Symaddr(s *LSym) int64 {
- if !s.Reachable {
+ if !s.Attr.Reachable() {
Diag("unreachable symbol in symaddr - %s", s.Name)
}
return s.Value
s := Linklookup(Ctxt, p, 0)
s.Type = int16(t)
s.Value = v
- s.Reachable = true
- s.Special = 1
- s.Local = true
+ s.Attr |= AttrReachable
+ s.Attr |= AttrSpecial
+ s.Attr |= AttrLocal
}
func datoff(addr int64) int64 {
if r.Sym.Type == obj.Sxxx || r.Sym.Type == obj.SXREF {
Diag("undefined: %s", r.Sym.Name)
}
- if !r.Sym.Reachable {
+ if !r.Sym.Attr.Reachable() {
Diag("use of unreachable symbol: %s", r.Sym.Name)
}
}
)
type LSym struct {
- Name string
- Extname string
- Type int16
- Version int16
- Dupok uint8
- External uint8
- Nosplit uint8
- Reachable bool
- Cgoexport uint8
- Special uint8
- Stkcheck uint8
- Hidden bool
- Leaf uint8
- Localentry uint8
- Onlist uint8
- // ElfType is set for symbols read from shared libraries by ldshlibsyms. It
- // is not set for symbols defined by the packages being linked or by symbols
- // read by ldelf (and so is left as elf.STT_NOTYPE).
- ElfType elf.SymType
+ Name string
+ Extname string
+ Type int16
+ Version int16
+ Attr Attribute
+ Localentry uint8
Dynid int32
Plt int32
Got int32
Locals int32
Value int64
Size int64
+ // ElfType is set for symbols read from shared libraries by ldshlibsyms. It
+ // is not set for symbols defined by the packages being linked or by symbols
+ // read by ldelf (and so is left as elf.STT_NOTYPE).
+ ElfType elf.SymType
Next *LSym
Sub *LSym
Outer *LSym
Pcln *Pcln
P []byte
R []Reloc
- Local bool
}
func (s *LSym) String() string {
}
}
+// Attribute is a set of common symbol attributes.
+type Attribute int16
+
+const (
+ AttrDuplicateOK Attribute = 1 << iota
+ AttrExternal
+ AttrNoSplit
+ AttrReachable
+ AttrCgoExportDynamic
+ AttrCgoExportStatic
+ AttrSpecial
+ AttrStackCheck
+ AttrHidden
+ AttrOnList
+ AttrLocal
+)
+
+func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 }
+func (a Attribute) External() bool { return a&AttrExternal != 0 }
+func (a Attribute) NoSplit() bool { return a&AttrNoSplit != 0 }
+func (a Attribute) Reachable() bool { return a&AttrReachable != 0 }
+func (a Attribute) CgoExportDynamic() bool { return a&AttrCgoExportDynamic != 0 }
+func (a Attribute) CgoExportStatic() bool { return a&AttrCgoExportStatic != 0 }
+func (a Attribute) Special() bool { return a&AttrSpecial != 0 }
+func (a Attribute) StackCheck() bool { return a&AttrStackCheck != 0 }
+func (a Attribute) Hidden() bool { return a&AttrHidden != 0 }
+func (a Attribute) OnList() bool { return a&AttrOnList != 0 }
+func (a Attribute) Local() bool { return a&AttrLocal != 0 }
+
+func (a Attribute) CgoExport() bool {
+ return a.CgoExportDynamic() || a.CgoExportStatic()
+}
+
+func (a *Attribute) Set(flag Attribute, value bool) {
+ if value {
+ *a |= flag
+ } else {
+ *a &= ^flag
+ }
+}
+
type Reloc struct {
Off int32
Siz uint8
s := Linklookup(Ctxt, ".machosymstr", 0)
s.Type = obj.SMACHOSYMSTR
- s.Reachable = true
+ s.Attr |= AttrReachable
Adduint8(Ctxt, s, ' ')
Adduint8(Ctxt, s, '\x00')
s = Linklookup(Ctxt, ".machosymtab", 0)
s.Type = obj.SMACHOSYMTAB
- s.Reachable = true
+ s.Attr |= AttrReachable
if Linkmode != LinkExternal {
s := Linklookup(Ctxt, ".plt", 0) // will be __symbol_stub
s.Type = obj.SMACHOPLT
- s.Reachable = true
+ s.Attr |= AttrReachable
s = Linklookup(Ctxt, ".got", 0) // will be __nl_symbol_ptr
s.Type = obj.SMACHOGOT
- s.Reachable = true
+ s.Attr |= AttrReachable
s.Align = 4
s = Linklookup(Ctxt, ".linkedit.plt", 0) // indirect table for .plt
s.Type = obj.SMACHOINDIRECTPLT
- s.Reachable = true
+ s.Attr |= AttrReachable
s = Linklookup(Ctxt, ".linkedit.got", 0) // indirect table for .got
s.Type = obj.SMACHOINDIRECTGOT
- s.Reachable = true
+ s.Attr |= AttrReachable
}
}
if s.Type == obj.SDYNIMPORT {
return SymKindUndef
}
- if s.Cgoexport != 0 {
+ if s.Attr.CgoExport() {
return SymKindExtdef
}
return SymKindLocal
genasmsym(put)
for _, s := range Ctxt.Allsym {
if s.Type == obj.SDYNIMPORT || s.Type == obj.SHOSTOBJ {
- if s.Reachable {
+ if s.Attr.Reachable() {
put(s, "", 'D', 0, 0, 0, nil)
}
}
// So we sort them here and pre-allocate dynid for them
// See https://golang.org/issue/4029
for i := 0; i < len(dynexp); i++ {
- dynexp[i].Reachable = true
+ dynexp[i].Attr |= AttrReachable
}
machogenasmsym(addsym)
sortsym = make([]*LSym, nsortsym)
Adduint16(Ctxt, symtab, 0) // desc
adduintxx(Ctxt, symtab, 0, Thearch.Ptrsize) // no value
} else {
- if s.Cgoexport != 0 {
+ if s.Attr.CgoExport() {
Adduint8(Ctxt, symtab, 0x0f)
} else {
Adduint8(Ctxt, symtab, 0x0e)
sect.Reloff = uint64(Cpos())
var sym *LSym
for sym = first; sym != nil; sym = sym.Next {
- if !sym.Reachable {
+ if !sym.Attr.Reachable() {
continue
}
if uint64(sym.Value) >= sect.Vaddr {
var r *Reloc
var ri int
for ; sym != nil; sym = sym.Next {
- if !sym.Reachable {
+ if !sym.Attr.Reachable() {
continue
}
if sym.Value >= int64(eaddr) {
log.Fatalf("invalid symbol version %d", v)
}
flags := rdint(f)
- dupok := flags & 1
- local := false
- if flags&2 != 0 {
- local = true
- }
+ dupok := flags&1 != 0
+ local := flags&2 != 0
size := rdint(f)
typ := rdsym(ctxt, f, pkg)
data := rddata(f)
if (s.Type == obj.SDATA || s.Type == obj.SBSS || s.Type == obj.SNOPTRBSS) && len(s.P) == 0 && len(s.R) == 0 {
goto overwrite
}
- if s.Type != obj.SBSS && s.Type != obj.SNOPTRBSS && dupok == 0 && s.Dupok == 0 {
+ if s.Type != obj.SBSS && s.Type != obj.SNOPTRBSS && !dupok && !s.Attr.DuplicateOK() {
log.Fatalf("duplicate symbol %s (types %d and %d) in %s and %s", s.Name, s.Type, t, s.File, pn)
}
if len(s.P) > 0 {
overwrite:
s.File = pkg
- s.Dupok = uint8(dupok)
+ if dupok {
+ s.Attr |= AttrDuplicateOK
+ }
if t == obj.SXREF {
log.Fatalf("bad sxref")
}
if s.Size < int64(size) {
s.Size = int64(size)
}
- s.Local = local
+ s.Attr.Set(AttrLocal, local)
if typ != nil { // if bss sym defined multiple times, take type from any one def
s.Gotype = typ
}
if s.Type == obj.STEXT {
s.Args = rdint32(f)
s.Locals = rdint32(f)
- s.Nosplit = rduint8(f)
- v := rdint(f)
- s.Leaf = uint8(v & 1)
+ if rduint8(f) != 0 {
+ s.Attr |= AttrNoSplit
+ }
+ rdint(f) // v&1 is Leaf, currently unused
n := rdint(f)
var a *Auto
for i := 0; i < n; i++ {
}
if dup == nil {
- if s.Onlist != 0 {
+ if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Onlist = 1
+ s.Attr |= AttrOnList
if ctxt.Etextp != nil {
ctxt.Etextp.Next = s
} else {
if s.Type != 0 {
fmt.Fprintf(ctxt.Bso, "t=%d ", s.Type)
}
- if s.Dupok != 0 {
+ if s.Attr.DuplicateOK() {
fmt.Fprintf(ctxt.Bso, "dupok ")
}
- if s.Nosplit != 0 {
+ if s.Attr.NoSplit() {
fmt.Fprintf(ctxt.Bso, "nosplit ")
}
fmt.Fprintf(ctxt.Bso, "size=%d value=%d", int64(s.Size), int64(s.Value))
x, _ := strconv.ParseUint(s.Name[5:], 16, 32)
i32 := int32(x)
s.Type = obj.SRODATA
- s.Local = true
+ s.Attr |= AttrLocal
Adduint32(ctxt, s, uint32(i32))
- s.Reachable = false
+ s.Attr.Set(AttrReachable, false)
} else if strings.HasPrefix(s.Name, "$f64.") || strings.HasPrefix(s.Name, "$i64.") {
x, _ := strconv.ParseUint(s.Name[5:], 16, 64)
i64 := int64(x)
s.Type = obj.SRODATA
- s.Local = true
+ s.Attr |= AttrLocal
Adduint64(ctxt, s, uint64(i64))
- s.Reachable = false
+ s.Attr.Set(AttrReachable, false)
}
}
if v == 0 && strings.HasPrefix(s.Name, "runtime.gcbits.") {
- s.Local = true
+ s.Attr |= AttrLocal
}
return s
}
funcdata_bytes := int64(0)
ftab := Linklookup(Ctxt, "runtime.pclntab", 0)
ftab.Type = obj.SPCLNTAB
- ftab.Reachable = true
+ ftab.Attr |= AttrReachable
// See golang.org/s/go12symtab for the format. Briefly:
// 8-byte header
func findfunctab() {
t := Linklookup(Ctxt, "runtime.findfunctab", 0)
t.Type = obj.SRODATA
- t.Reachable = true
- t.Local = true
+ t.Attr |= AttrReachable
+ t.Attr |= AttrLocal
// find min and max address
min := Ctxt.Textp.Value
dr = nil
var m *Imp
for _, s := range Ctxt.Allsym {
- if !s.Reachable || s.Type != obj.SDYNIMPORT {
+ if !s.Attr.Reachable() || s.Type != obj.SDYNIMPORT {
continue
}
for d = dr; d != nil; d = d.next {
dynName += fmt.Sprintf("@%d", m.argsize)
}
dynSym := Linklookup(Ctxt, dynName, 0)
- dynSym.Reachable = true
+ dynSym.Attr |= AttrReachable
dynSym.Type = obj.SHOSTOBJ
r := Addrel(m.s)
r.Sym = dynSym
}
} else {
dynamic := Linklookup(Ctxt, ".windynamic", 0)
- dynamic.Reachable = true
+ dynamic.Attr |= AttrReachable
dynamic.Type = obj.SWINDOWS
for d := dr; d != nil; d = d.next {
for m = d.ms; m != nil; m = m.next {
func initdynexport() {
nexport = 0
for _, s := range Ctxt.Allsym {
- if !s.Reachable || s.Cgoexport&CgoExportDynamic == 0 {
+ if !s.Attr.Reachable() || !s.Attr.CgoExportDynamic() {
continue
}
if nexport+1 > len(dexport) {
sect.Reloff = uint64(Cpos())
var sym *LSym
for sym = first; sym != nil; sym = sym.Next {
- if !sym.Reachable {
+ if !sym.Attr.Reachable() {
continue
}
if uint64(sym.Value) >= sect.Vaddr {
var r *Reloc
var ri int
for ; sym != nil; sym = sym.Next {
- if !sym.Reachable {
+ if !sym.Attr.Reachable() {
continue
}
if sym.Value >= int64(eaddr) {
/* relocation table */
rel := Linklookup(Ctxt, ".rel", 0)
- rel.Reachable = true
+ rel.Attr |= AttrReachable
rel.Type = obj.SELFROSECT
initdynimport()
if coffsym != nil {
// only windows/386 requires underscore prefix on external symbols
- if Thearch.Thechar == '8' && Linkmode == LinkExternal && (s.Type == obj.SHOSTOBJ || s.Cgoexport != 0) && s.Name == s.Extname {
+ if Thearch.Thechar == '8' && Linkmode == LinkExternal && (s.Type == obj.SHOSTOBJ || s.Attr.CgoExport()) && s.Name == s.Extname {
s.Name = "_" + s.Name
}
cs := &coffsym[ncoffsym]
// maybe one day STB_WEAK.
bind := STB_GLOBAL
- if ver != 0 || (x.Type&obj.SHIDDEN != 0) || x.Local {
+ if ver != 0 || (x.Type&obj.SHIDDEN != 0) || x.Attr.Local() {
bind = STB_LOCAL
}
// To avoid filling the dynamic table with lots of unnecessary symbols,
// mark all Go symbols local (not global) in the final executable.
// But when we're dynamically linking, we need all those global symbols.
- if !DynlinkingGo() && Linkmode == LinkExternal && x.Cgoexport&CgoExportStatic == 0 && elfshnum != SHN_UNDEF {
+ if !DynlinkingGo() && Linkmode == LinkExternal && !x.Attr.CgoExportStatic() && elfshnum != SHN_UNDEF {
bind = STB_LOCAL
}
s.Type = obj.SRODATA
s.Size = 0
- s.Reachable = true
+ s.Attr |= AttrReachable
xdefine("runtime.egcdata", obj.SRODATA, 0)
s = Linklookup(Ctxt, "runtime.gcbss", 0)
s.Type = obj.SRODATA
s.Size = 0
- s.Reachable = true
+ s.Attr |= AttrReachable
xdefine("runtime.egcbss", obj.SRODATA, 0)
// pseudo-symbols to mark locations of type, string, and go string data.
s.Type = obj.STYPE
s.Size = 0
- s.Reachable = true
+ s.Attr |= AttrReachable
symtype = s
s = Linklookup(Ctxt, "typerel.*", 0)
s.Type = obj.STYPERELRO
s.Size = 0
- s.Reachable = true
+ s.Attr |= AttrReachable
symtyperel = s
} else if !DynlinkingGo() {
s = Linklookup(Ctxt, "type.*", 0)
s.Type = obj.STYPE
s.Size = 0
- s.Reachable = true
+ s.Attr |= AttrReachable
symtype = s
symtyperel = s
}
s = Linklookup(Ctxt, "go.string.*", 0)
s.Type = obj.SGOSTRING
- s.Local = true
+ s.Attr |= AttrLocal
s.Size = 0
- s.Reachable = true
+ s.Attr |= AttrReachable
symgostring := s
s = Linklookup(Ctxt, "go.func.*", 0)
s.Type = obj.SGOFUNC
- s.Local = true
+ s.Attr |= AttrLocal
s.Size = 0
- s.Reachable = true
+ s.Attr |= AttrReachable
symgofunc := s
s = Linklookup(Ctxt, "runtime.gcbits.*", 0)
s.Type = obj.SGCBITS
- s.Local = true
+ s.Attr |= AttrLocal
s.Size = 0
- s.Reachable = true
+ s.Attr |= AttrReachable
symgcbits := s
symtypelink := Linklookup(Ctxt, "runtime.typelink", 0)
symtypelink.Type = obj.STYPELINK
symt = Linklookup(Ctxt, "runtime.symtab", 0)
- symt.Local = true
+ symt.Attr |= AttrLocal
symt.Type = obj.SSYMTAB
symt.Size = 0
- symt.Reachable = true
+ symt.Attr |= AttrReachable
ntypelinks := 0
// just defined above will be first.
// hide the specific symbols.
for _, s := range Ctxt.Allsym {
- if !s.Reachable || s.Special != 0 || s.Type != obj.SRODATA {
+ if !s.Attr.Reachable() || s.Attr.Special() || s.Type != obj.SRODATA {
continue
}
if strings.HasPrefix(s.Name, "type.") && !DynlinkingGo() {
- s.Hidden = true
+ s.Attr |= AttrHidden
if UseRelro() && len(s.R) > 0 {
s.Type = obj.STYPERELRO
s.Outer = symtyperel
if strings.HasPrefix(s.Name, "go.typelink.") {
ntypelinks++
s.Type = obj.STYPELINK
- s.Hidden = true
+ s.Attr |= AttrHidden
s.Outer = symtypelink
}
if strings.HasPrefix(s.Name, "go.string.") {
s.Type = obj.SGOSTRING
- s.Hidden = true
+ s.Attr |= AttrHidden
s.Outer = symgostring
}
if strings.HasPrefix(s.Name, "runtime.gcbits.") {
s.Type = obj.SGCBITS
- s.Hidden = true
+ s.Attr |= AttrHidden
s.Outer = symgcbits
}
if strings.HasPrefix(s.Name, "go.func.") {
s.Type = obj.SGOFUNC
- s.Hidden = true
+ s.Attr |= AttrHidden
s.Outer = symgofunc
}
if strings.HasPrefix(s.Name, "gcargs.") || strings.HasPrefix(s.Name, "gclocals.") || strings.HasPrefix(s.Name, "gclocals·") {
s.Type = obj.SGOFUNC
- s.Hidden = true
+ s.Attr |= AttrHidden
s.Outer = symgofunc
s.Align = 4
liveness += (s.Size + int64(s.Align) - 1) &^ (int64(s.Align) - 1)
if Buildmode == BuildmodeShared {
abihashgostr := Linklookup(Ctxt, "go.link.abihash."+filepath.Base(outfile), 0)
- abihashgostr.Reachable = true
+ abihashgostr.Attr |= AttrReachable
abihashgostr.Type = obj.SRODATA
hashsym := Linklookup(Ctxt, "go.link.abihashbytes", 0)
Addaddr(Ctxt, abihashgostr, hashsym)
addgostring(moduledata, "go.link.thismodulename", thismodulename)
modulehashes := Linklookup(Ctxt, "go.link.abihashes", 0)
- modulehashes.Reachable = true
- modulehashes.Local = true
+ modulehashes.Attr |= AttrReachable
+ modulehashes.Attr |= AttrLocal
modulehashes.Type = obj.SRODATA
for i, shlib := range Ctxt.Shlibs {
// modulehashes[i].runtimehash
abihash := Linklookup(Ctxt, "go.link.abihash."+modulename, 0)
- abihash.Reachable = true
+ abihash.Attr |= AttrReachable
Addaddr(Ctxt, modulehashes, abihash)
}
n = fmt.Sprintf("%s.%s", s.Name, r.Sym.Name)
stub = ld.Linklookup(ld.Ctxt, n, 0)
- stub.Reachable = stub.Reachable || s.Reachable
+ if s.Attr.Reachable() {
+ stub.Attr |= ld.AttrReachable
+ }
if stub.Size == 0 {
// Need outer to resolve .TOC.
stub.Outer = s
if addmoduledata.Type == obj.STEXT {
return
}
- addmoduledata.Reachable = true
+ addmoduledata.Attr |= ld.AttrReachable
initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0)
initfunc.Type = obj.STEXT
- initfunc.Local = true
- initfunc.Reachable = true
+ initfunc.Attr |= ld.AttrLocal
+ initfunc.Attr |= ld.AttrReachable
o := func(op uint32) {
ld.Adduint32(ld.Ctxt, initfunc, op)
}
ld.Ctxt.Etextp = initfunc
initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0)
- initarray_entry.Reachable = true
- initarray_entry.Local = true
+ initarray_entry.Attr |= ld.AttrReachable
+ initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Type = obj.SINITARR
ld.Addaddr(ld.Ctxt, initarray_entry, initfunc)
}
// Append 4 bytes to s and create a R_CALL relocation targeting t to fill them in.
func addcall(ctxt *ld.Link, s *ld.LSym, t *ld.LSym) {
- s.Reachable = true
+ s.Attr |= ld.AttrReachable
i := s.Size
s.Size += 4
ld.Symgrow(ctxt, s, s.Size)
thunkfunc := ld.Linklookup(ld.Ctxt, "__x86.get_pc_thunk.cx", 0)
thunkfunc.Type = obj.STEXT
- thunkfunc.Local = true
- thunkfunc.Reachable = true
+ thunkfunc.Attr |= ld.AttrLocal
+ thunkfunc.Attr |= ld.AttrReachable
o := func(op ...uint8) {
for _, op1 := range op {
ld.Adduint8(ld.Ctxt, thunkfunc, op1)
return
}
- addmoduledata.Reachable = true
+ addmoduledata.Attr |= ld.AttrReachable
initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0)
initfunc.Type = obj.STEXT
- initfunc.Local = true
- initfunc.Reachable = true
+ initfunc.Attr |= ld.AttrLocal
+ initfunc.Attr |= ld.AttrReachable
o = func(op ...uint8) {
for _, op1 := range op {
ld.Adduint8(ld.Ctxt, initfunc, op1)
ld.Ctxt.Etextp.Next = initfunc
ld.Ctxt.Etextp = initfunc
initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0)
- initarray_entry.Reachable = true
- initarray_entry.Local = true
+ initarray_entry.Attr |= ld.AttrReachable
+ initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Type = obj.SINITARR
ld.Addaddr(ld.Ctxt, initarray_entry, initfunc)
}
ld.Linkmode = ld.LinkExternal
got := ld.Linklookup(ld.Ctxt, "_GLOBAL_OFFSET_TABLE_", 0)
got.Type = obj.SDYNIMPORT
- got.Reachable = true
+ got.Attr |= ld.AttrReachable
}
switch ld.HEADTYPE {