From: Cherry Zhang Date: Fri, 24 Apr 2020 18:57:20 +0000 (-0400) Subject: [dev.link] cmd/link: use new dodata on darwin/amd64 X-Git-Tag: go1.15beta1~270^2^2~28 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=b2fde1098a151f89c7a20d0fe322dfb052211786;p=gostls13.git [dev.link] cmd/link: use new dodata on darwin/amd64 This probably breaks darwin/arm64. Will fix. Change-Id: I8be168985124f971e9d8ab5bc95c303336dd705b Reviewed-on: https://go-review.googlesource.com/c/go/+/230019 Reviewed-by: Than McIntosh --- diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index 2022c43bff..48eab03314 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -1355,8 +1355,7 @@ func (ctxt *Link) dodata2(symGroupType []sym.SymKind) { // // On darwin, we need the symbol table numbers for dynreloc. if ctxt.HeadType == objabi.Hdarwin { - panic("not yet implemented for darwin") - // machosymorder(ctxt) + machosymorder(ctxt) } state.dynreloc2(ctxt) diff --git a/src/cmd/link/internal/ld/data2.go b/src/cmd/link/internal/ld/data2.go index 3eb45818d2..5c88fbaa57 100644 --- a/src/cmd/link/internal/ld/data2.go +++ b/src/cmd/link/internal/ld/data2.go @@ -45,7 +45,8 @@ func (ctxt *Link) dodata() { // // On darwin, we need the symbol table numbers for dynreloc. if ctxt.HeadType == objabi.Hdarwin { - machosymorder(ctxt) + panic("not supported") + //machosymorder(ctxt) } state.dynreloc(ctxt) diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go index baa1f4094a..4dc7f819eb 100644 --- a/src/cmd/link/internal/ld/macho.go +++ b/src/cmd/link/internal/ld/macho.go @@ -8,6 +8,7 @@ import ( "bytes" "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/loader" "cmd/link/internal/sym" "debug/macho" "encoding/binary" @@ -216,7 +217,7 @@ const ( var nkind [NumSymKind]int -var sortsym []*sym.Symbol +var sortsym []loader.Sym var nsortsym int @@ -743,106 +744,125 @@ func Asmbmacho(ctxt *Link) { } } -func symkind(s *sym.Symbol) int { - if s.Type == sym.SDYNIMPORT { +func symkind(ldr *loader.Loader, s loader.Sym) int { + if ldr.SymType(s) == sym.SDYNIMPORT { return SymKindUndef } - if s.Attr.CgoExport() { + if ldr.AttrCgoExport(s) { return SymKindExtdef } return SymKindLocal } -func addsym(ctxt *Link, s *sym.Symbol, name string, type_ SymbolType, addr int64, gotype *sym.Symbol) { - if s == nil { - return - } - - switch type_ { - default: - return +func collectmachosyms(ctxt *Link) { + ldr := ctxt.loader - case DataSym, BSSSym, TextSym: - break + addsym := func(s loader.Sym) { + sortsym = append(sortsym, s) + nkind[symkind(ldr, s)]++ } - if sortsym != nil { - sortsym[nsortsym] = s - nkind[symkind(s)]++ + // Add special runtime.text and runtime.etext symbols. + // We've already included this symbol in Textp on darwin if ctxt.DynlinkingGo(). + // See data.go:/textaddress + if !ctxt.DynlinkingGo() { + s := ldr.Lookup("runtime.text", 0) + if ldr.SymType(s) == sym.STEXT { + addsym(s) + } + s = ldr.Lookup("runtime.etext", 0) + if ldr.SymType(s) == sym.STEXT { + addsym(s) + } } - nsortsym++ -} - -type machoscmp []*sym.Symbol - -func (x machoscmp) Len() int { - return len(x) -} - -func (x machoscmp) Swap(i, j int) { - x[i], x[j] = x[j], x[i] -} - -func (x machoscmp) Less(i, j int) bool { - s1 := x[i] - s2 := x[j] + // Add text symbols. + for _, s := range ctxt.Textp2 { + addsym(s) + } - k1 := symkind(s1) - k2 := symkind(s2) - if k1 != k2 { - return k1 < k2 + shouldBeInSymbolTable := func(s loader.Sym) bool { + if ldr.AttrNotInSymbolTable(s) { + return false + } + name := ldr.RawSymName(s) // TODO: try not to read the name + if name == "" || name[0] == '.' { + return false + } + return true } - return s1.Extname() < s2.Extname() -} + // Add data symbols and external references. + for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ { + if !ldr.AttrReachable(s) { + continue + } + t := ldr.SymType(s) + if t >= sym.SELFRXSECT && t < sym.SXREF { // data sections handled in dodata + if t == sym.STLSBSS { + // TLSBSS is not used on darwin. See data.go:allocateDataSections + continue + } + if !shouldBeInSymbolTable(s) { + continue + } + addsym(s) + } + + switch t { + case sym.SDYNIMPORT, sym.SHOSTOBJ, sym.SUNDEFEXT, sym.SCONST: + addsym(s) + } -func machogenasmsym(ctxt *Link) { - genasmsym(ctxt, addsym) - for _, s := range ctxt.Syms.Allsym { // Some 64-bit functions have a "$INODE64" or "$INODE64$UNIX2003" suffix. - if s.Type == sym.SDYNIMPORT && s.Dynimplib() == "/usr/lib/libSystem.B.dylib" { + if t == sym.SDYNIMPORT && ldr.SymDynimplib(s) == "/usr/lib/libSystem.B.dylib" { // But only on macOS. if machoPlatform == PLATFORM_MACOS { - switch n := s.Extname(); n { + switch n := ldr.SymExtname(s); n { case "fdopendir": switch objabi.GOARCH { case "amd64": - s.SetExtname(n + "$INODE64") + ldr.SetSymExtname(s, n+"$INODE64") case "386": - s.SetExtname(n + "$INODE64$UNIX2003") + ldr.SetSymExtname(s, n+"$INODE64$UNIX2003") } case "readdir_r", "getfsstat": switch objabi.GOARCH { case "amd64", "386": - s.SetExtname(n + "$INODE64") + ldr.SetSymExtname(s, n+"$INODE64") } } } } - - if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ || s.Type == sym.SUNDEFEXT { - if s.Attr.Reachable() { - addsym(ctxt, s, "", DataSym, 0, nil) - } - } } + + nsortsym = len(sortsym) } func machosymorder(ctxt *Link) { + ldr := ctxt.loader + // On Mac OS X Mountain Lion, we must sort exported symbols // So we sort them here and pre-allocate dynid for them // See https://golang.org/issue/4029 - for i := range dynexp { - dynexp[i].Attr |= sym.AttrReachable - } - machogenasmsym(ctxt) - sortsym = make([]*sym.Symbol, nsortsym) - nsortsym = 0 - machogenasmsym(ctxt) - sort.Sort(machoscmp(sortsym[:nsortsym])) - for i := 0; i < nsortsym; i++ { - sortsym[i].Dynid = int32(i) + for _, s := range ctxt.dynexp2 { + if !ldr.AttrReachable(s) { + panic("dynexp symbol is not reachable") + } + } + collectmachosyms(ctxt) + sort.Slice(sortsym[:nsortsym], func(i, j int) bool { + s1 := sortsym[i] + s2 := sortsym[j] + k1 := symkind(ldr, s1) + k2 := symkind(ldr, s2) + if k1 != k2 { + return k1 < k2 + } + return ldr.SymExtname(s1) < ldr.SymExtname(s2) // Note: unnamed symbols are not added in collectmachosyms + }) + for i, s := range sortsym { + ldr.SetSymDynid(s, int32(i)) } } @@ -877,7 +897,7 @@ func machosymtab(ctxt *Link) { symstr := ctxt.Syms.Lookup(".machosymstr", 0) for i := 0; i < nsortsym; i++ { - s := sortsym[i] + s := ctxt.loader.Syms[sortsym[i]] symtab.AddUint32(ctxt.Arch, uint32(symstr.Size)) export := machoShouldExport(ctxt, s) diff --git a/src/cmd/link/internal/ld/main.go b/src/cmd/link/internal/ld/main.go index c361773c3c..35363aa4ee 100644 --- a/src/cmd/link/internal/ld/main.go +++ b/src/cmd/link/internal/ld/main.go @@ -202,8 +202,16 @@ func Main(arch *sys.Arch, theArch Arch) { if *flagnewDoData { // New dodata() is currently only implemented for selected targets. - if !(ctxt.IsElf() && - (ctxt.IsAMD64() || ctxt.Is386())) { + switch { + case ctxt.IsElf(): + if !(ctxt.IsAMD64() || ctxt.Is386()) { + *flagnewDoData = false + } + case ctxt.IsDarwin(): + if !ctxt.IsAMD64() { + *flagnewDoData = false + } + default: *flagnewDoData = false } }