]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: use new dodata on darwin/amd64
authorCherry Zhang <cherryyz@google.com>
Fri, 24 Apr 2020 18:57:20 +0000 (14:57 -0400)
committerCherry Zhang <cherryyz@google.com>
Sat, 25 Apr 2020 01:21:06 +0000 (01:21 +0000)
This probably breaks darwin/arm64. Will fix.

Change-Id: I8be168985124f971e9d8ab5bc95c303336dd705b
Reviewed-on: https://go-review.googlesource.com/c/go/+/230019
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/data2.go
src/cmd/link/internal/ld/macho.go
src/cmd/link/internal/ld/main.go

index 2022c43bff55c65f67beff77f45faf792d03f48a..48eab03314e3981fed1646ae49d06bb30d1a183e 100644 (file)
@@ -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)
 
index 3eb45818d2e46cb8b9eb577c6fb25096ce18b0b7..5c88fbaa574c6b705733261c1a35088524241e4b 100644 (file)
@@ -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)
 
index baa1f4094a814c58fe670f304948f34e5a1924d3..4dc7f819eb45466412caab01d2774785d1d5508d 100644 (file)
@@ -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)
index c361773c3ccf7b8dee488321001efc916a64fd76..35363aa4eee3bb158c7e17a2ea41ff1272175639 100644 (file)
@@ -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
                }
        }