]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: convert doxcoff to new style
authorCherry Zhang <cherryyz@google.com>
Tue, 24 Mar 2020 16:08:36 +0000 (12:08 -0400)
committerCherry Zhang <cherryyz@google.com>
Wed, 25 Mar 2020 15:20:40 +0000 (15:20 +0000)
Change-Id: Ic1e4ed6c14e049b1ba2f7c00f986433ab7ebe932
Reviewed-on: https://go-review.googlesource.com/c/go/+/225202
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/ld/dwarf.go
src/cmd/link/internal/ld/main.go
src/cmd/link/internal/ld/xcoff.go
src/cmd/link/internal/loadelf/ldelf.go
src/cmd/link/internal/loader/loader.go
src/cmd/link/internal/loader/loader_test.go
src/cmd/link/internal/loader/symbolbuilder.go

index 3c5cae8aed26bb0b5e8a9051c4f19a09aee76c2b..9f67a15c72ce16c2733ae2aa86833624974b809c 100644 (file)
@@ -461,7 +461,7 @@ func (d *dwctxt2) dotypedef(parent *dwarf.DWDie, gotype loader.Sym, name string,
        // Create a new loader symbol for the typedef. We no longer
        // do lookups of typedef symbols by name, so this is going
        // to be an anonymous symbol (we want this for perf reasons).
-       tds := d.ldr.CreateExtSym("")
+       tds := d.ldr.CreateExtSym("", 0)
        tdsu := d.ldr.MakeSymbolUpdater(tds)
        tdsu.SetType(sym.SDWARFINFO)
        def.Sym = dwSym(tds)
index 23873166ae396794187dbf20758ef331bae63e35..a94280dc0b2f52e6116f78a4e32685b8a36fadc3 100644 (file)
@@ -272,13 +272,13 @@ func Main(arch *sys.Arch, theArch Arch) {
                bench.Start("dope")
                ctxt.dope()
        }
-       bench.Start("loadlibfull")
-       setupdynexp(ctxt)
-       ctxt.loadlibfull() // XXX do it here for now
        if ctxt.IsAIX() {
                bench.Start("doxcoff")
                ctxt.doxcoff()
        }
+       bench.Start("loadlibfull")
+       setupdynexp(ctxt)
+       ctxt.loadlibfull() // XXX do it here for now
        if ctxt.IsWindows() {
                bench.Start("windynrelocsyms")
                ctxt.windynrelocsyms()
index 5d36622bad47a58cbd5f996d1eca9522ee103d91..fc5d2358b8a378d8fc36cdb97402c5c50a30fe1e 100644 (file)
@@ -7,6 +7,7 @@ package ld
 import (
        "bytes"
        "cmd/internal/objabi"
+       "cmd/link/internal/loader"
        "cmd/link/internal/sym"
        "encoding/binary"
        "io/ioutil"
@@ -338,7 +339,7 @@ type XcoffLdSym64 struct {
 }
 
 type xcoffLoaderSymbol struct {
-       sym    *sym.Symbol
+       sym    loader.Sym
        smtype int8
        smclas int8
 }
@@ -415,6 +416,8 @@ type xcoffFile struct {
        dynLibraries    map[string]int       // Dynamic libraries in .loader section. The integer represents its import file number (- 1)
        loaderSymbols   []*xcoffLoaderSymbol // symbols inside .loader symbol table
        loaderReloc     []*xcoffLoaderReloc  // Reloc that must be made inside loader
+
+       ldr *loader.Loader // XXX keep a reference here for now, as it is needed in Xcoffadddynrel. will clean up in the next CL.
 }
 
 // Var used by XCOFF Generation algorithms
@@ -1031,9 +1034,13 @@ func (f *xcoffFile) asmaixsym(ctxt *Link) {
 }
 
 func (f *xcoffFile) genDynSym(ctxt *Link) {
-       var dynsyms []*sym.Symbol
-       for _, s := range ctxt.Syms.Allsym {
-               if s.Type != sym.SHOSTOBJ && s.Type != sym.SDYNIMPORT {
+       ldr := ctxt.loader
+       var dynsyms []loader.Sym
+       for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
+               if !ldr.AttrReachable(s) {
+                       continue
+               }
+               if t := ldr.SymType(s); t != sym.SHOSTOBJ && t != sym.SDYNIMPORT {
                        continue
                }
                dynsyms = append(dynsyms, s)
@@ -1042,12 +1049,10 @@ func (f *xcoffFile) genDynSym(ctxt *Link) {
        for _, s := range dynsyms {
                f.adddynimpsym(ctxt, s)
 
-               if _, ok := f.dynLibraries[s.Dynimplib()]; !ok {
-                       f.dynLibraries[s.Dynimplib()] = len(f.dynLibraries)
+               if _, ok := f.dynLibraries[ldr.SymDynimplib(s)]; !ok {
+                       f.dynLibraries[ldr.SymDynimplib(s)] = len(f.dynLibraries)
                }
-
        }
-
 }
 
 // (*xcoffFile)adddynimpsym adds the dynamic symbol "s" to a XCOFF file.
@@ -1057,30 +1062,32 @@ func (f *xcoffFile) genDynSym(ctxt *Link) {
 // However, there is no writing protection on those symbols and
 // it might need to be added.
 // TODO(aix): Handles dynamic symbols without library.
-func (f *xcoffFile) adddynimpsym(ctxt *Link, s *sym.Symbol) {
+func (f *xcoffFile) adddynimpsym(ctxt *Link, s loader.Sym) {
        // Check that library name is given.
        // Pattern is already checked when compiling.
-       if ctxt.LinkMode == LinkInternal && s.Dynimplib() == "" {
-               Errorf(s, "imported symbol must have a given library")
+       ldr := ctxt.loader
+       if ctxt.IsInternal() && ldr.SymDynimplib(s) == "" {
+               ctxt.Errorf(s, "imported symbol must have a given library")
        }
 
-       s.Type = sym.SXCOFFTOC
+       sb := ldr.MakeSymbolUpdater(s)
+       sb.SetType(sym.SXCOFFTOC)
 
        // Create new dynamic symbol
-       extsym := ctxt.Syms.Lookup(s.Extname(), 0)
-       extsym.Type = sym.SDYNIMPORT
-       extsym.Attr |= sym.AttrReachable
-       extsym.SetDynimplib(s.Dynimplib())
-       extsym.SetExtname(s.Extname())
-       extsym.SetDynimpvers(s.Dynimpvers())
+       extsym := ldr.CreateSymForUpdate(ldr.SymExtname(s), 0)
+       extsym.SetType(sym.SDYNIMPORT)
+       extsym.SetReachable(true)
+       extsym.SetDynimplib(ldr.SymDynimplib(s))
+       extsym.SetExtname(ldr.SymExtname(s))
+       extsym.SetDynimpvers(ldr.SymDynimpvers(s))
 
        // Add loader symbol
        lds := &xcoffLoaderSymbol{
-               sym:    extsym,
+               sym:    extsym.Sym(),
                smtype: XTY_IMP,
                smclas: XMC_DS,
        }
-       if s.Name == "__n_pthreads" {
+       if ldr.SymName(s) == "__n_pthreads" {
                // Currently, all imported symbols made by cgo_import_dynamic are
                // syscall functions, except __n_pthreads which is a variable.
                // TODO(aix): Find a way to detect variables imported by cgo.
@@ -1089,9 +1096,14 @@ func (f *xcoffFile) adddynimpsym(ctxt *Link, s *sym.Symbol) {
        f.loaderSymbols = append(f.loaderSymbols, lds)
 
        // Relocation to retrieve the external address
-       s.AddBytes(make([]byte, 8))
-       s.SetAddr(ctxt.Arch, 0, extsym)
-
+       sb.AddBytes(make([]byte, 8))
+       sb.AddReloc(loader.Reloc{Off: 0, Size: uint8(ctxt.Arch.PtrSize), Type: objabi.R_ADDR, Sym: extsym.Sym()})
+       // TODO: maybe this could be
+       // sb.SetSize(0)
+       // sb.SetData(nil)
+       // sb.AddAddr(ctxt.Arch, extsym.Sym())
+       // If the size is not 0 to begin with, I don't think the added 8 bytes
+       // of zeros are necessary.
 }
 
 // Xcoffadddynrel adds a dynamic relocation in a XCOFF file.
@@ -1105,7 +1117,7 @@ func Xcoffadddynrel(target *Target, s *sym.Symbol, r *sym.Reloc) bool {
                return false
        }
 
-       ldr := &xcoffLoaderReloc{
+       xldr := &xcoffLoaderReloc{
                sym: s,
                rel: r,
        }
@@ -1118,8 +1130,8 @@ func Xcoffadddynrel(target *Target, s *sym.Symbol, r *sym.Reloc) bool {
                if s.Type == sym.SXCOFFTOC && r.Sym.Type == sym.SDYNIMPORT {
                        // Imported symbol relocation
                        for i, dynsym := range xfile.loaderSymbols {
-                               if dynsym.sym.Name == r.Sym.Name {
-                                       ldr.symndx = int32(i + 3) // +3 because of 3 section symbols
+                               if xfile.ldr.Syms[dynsym.sym].Name == r.Sym.Name {
+                                       xldr.symndx = int32(i + 3) // +3 because of 3 section symbols
                                        break
                                }
                        }
@@ -1129,12 +1141,12 @@ func Xcoffadddynrel(target *Target, s *sym.Symbol, r *sym.Reloc) bool {
                                Errorf(s, "unknown segment for .loader relocation with symbol %s", r.Sym.Name)
                        case &Segtext:
                        case &Segrodata:
-                               ldr.symndx = 0 // .text
+                               xldr.symndx = 0 // .text
                        case &Segdata:
                                if r.Sym.Type == sym.SBSS || r.Sym.Type == sym.SNOPTRBSS {
-                                       ldr.symndx = 2 // .bss
+                                       xldr.symndx = 2 // .bss
                                } else {
-                                       ldr.symndx = 1 // .data
+                                       xldr.symndx = 1 // .data
                                }
 
                        }
@@ -1144,10 +1156,10 @@ func Xcoffadddynrel(target *Target, s *sym.Symbol, r *sym.Reloc) bool {
                        return false
                }
 
-               ldr.rtype = 0x3F<<8 + XCOFF_R_POS
+               xldr.rtype = 0x3F<<8 + XCOFF_R_POS
        }
 
-       xfile.loaderReloc = append(xfile.loaderReloc, ldr)
+       xfile.loaderReloc = append(xfile.loaderReloc, xldr)
        return true
 }
 
@@ -1156,16 +1168,17 @@ func (ctxt *Link) doxcoff() {
                // All XCOFF files have dynamic symbols because of the syscalls.
                Exitf("-d is not available on AIX")
        }
+       ldr := ctxt.loader
 
        // TOC
-       toc := ctxt.Syms.Lookup("TOC", 0)
-       toc.Type = sym.SXCOFFTOC
-       toc.Attr |= sym.AttrReachable
-       toc.Attr |= sym.AttrVisibilityHidden
+       toc := ldr.CreateSymForUpdate("TOC", 0)
+       toc.SetType(sym.SXCOFFTOC)
+       toc.SetReachable(true)
+       toc.SetVisibilityHidden(true)
 
        // Add entry point to .loader symbols.
-       ep := ctxt.Syms.ROLookup(*flagEntrySymbol, 0)
-       if !ep.Attr.Reachable() {
+       ep := ldr.Lookup(*flagEntrySymbol, 0)
+       if ep == 0 || !ldr.AttrReachable(ep) {
                Exitf("wrong entry point")
        }
 
@@ -1177,43 +1190,45 @@ func (ctxt *Link) doxcoff() {
 
        xfile.genDynSym(ctxt)
 
-       for _, s := range ctxt.Syms.Allsym {
-               if strings.HasPrefix(s.Name, "TOC.") {
-                       s.Type = sym.SXCOFFTOC
+       xfile.ldr = ldr // XXX
+
+       for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
+               if strings.HasPrefix(ldr.SymName(s), "TOC.") {
+                       sb := ldr.MakeSymbolUpdater(s)
+                       sb.SetType(sym.SXCOFFTOC)
                }
        }
 
-       if ctxt.LinkMode == LinkExternal {
+       if ctxt.IsExternal() {
                // Change rt0_go name to match name in runtime/cgo:main().
-               rt0 := ctxt.Syms.ROLookup("runtime.rt0_go", 0)
-               rt0.SetExtname("runtime_rt0_go")
+               rt0 := ldr.Lookup("runtime.rt0_go", 0)
+               ldr.SetSymExtname(rt0, "runtime_rt0_go")
 
-               for _, s := range ctxt.Textp {
-                       if !s.Attr.CgoExport() {
+               nsym := loader.Sym(ldr.NSym())
+               for s := loader.Sym(1); s < nsym; s++ {
+                       if !ldr.AttrCgoExport(s) {
                                continue
                        }
+                       if ldr.SymVersion(s) != 0 { // sanity check
+                               panic("cgo_export on non-version 0 symbol")
+                       }
 
-                       name := s.Extname()
-                       if s.Type == sym.STEXT {
+                       if ldr.SymType(s) == sym.STEXT || ldr.SymType(s) == sym.SABIALIAS {
                                // On AIX, a exported function must have two symbols:
                                // - a .text symbol which must start with a ".".
                                // - a .data symbol which is a function descriptor.
                                //
-                               // XXX the old code was quite confusing -- it always
-                               // rename a version 0 symbol, even if s.Version is not
-                               // 0, but the descriptor still points to s.
-                               // And in xcoffCreateExportFile, it seems to expect a
-                               // name before the renaming.
-                               // I guess this happens to work as the ABIALIAS symbol
-                               // and the TEXT symbol have the same address.
-                               // (Do the same here for now, but using Extname.)
-                               s0 := ctxt.Syms.ROLookup(s.Name, 0)
-                               s0.SetExtname("." + name)
-
-                               desc := ctxt.Syms.Newsym(name, 0)
-                               desc.Type = sym.SNOPTRDATA
+                               // CgoExport attribute should only be set on a version 0
+                               // symbol, which can be TEXT or ABIALIAS.
+                               // (before, setupdynexp copies the attribute from the
+                               // alias to the aliased. Now we are before setupdynexp.)
+                               name := ldr.SymExtname(s)
+                               ldr.SetSymExtname(s, "."+name)
+
+                               desc := ldr.MakeSymbolUpdater(ldr.CreateExtSym(name, 0))
+                               desc.SetType(sym.SNOPTRDATA)
                                desc.AddAddr(ctxt.Arch, s)
-                               desc.AddAddr(ctxt.Arch, toc)
+                               desc.AddAddr(ctxt.Arch, toc.Sym())
                                desc.AddUint64(ctxt.Arch, 0)
                        }
                }
@@ -1253,18 +1268,19 @@ func (f *xcoffFile) writeLdrScn(ctxt *Link, globalOff uint64) {
                        Lsmtype: s.smtype,
                        Lsmclas: s.smclas,
                }
+               sym := ctxt.loader.Syms[s.sym]
                switch s.smtype {
                default:
-                       Errorf(s.sym, "unexpected loader symbol type: 0x%x", s.smtype)
+                       Errorf(sym, "unexpected loader symbol type: 0x%x", s.smtype)
                case XTY_ENT | XTY_SD:
-                       lds.Lvalue = uint64(s.sym.Value)
-                       lds.Lscnum = f.getXCOFFscnum(s.sym.Sect)
+                       lds.Lvalue = uint64(sym.Value)
+                       lds.Lscnum = f.getXCOFFscnum(sym.Sect)
                case XTY_IMP:
-                       lds.Lifile = int32(f.dynLibraries[s.sym.Dynimplib()] + 1)
+                       lds.Lifile = int32(f.dynLibraries[sym.Dynimplib()] + 1)
                }
                ldstr := &XcoffLdStr64{
-                       size: uint16(len(s.sym.Name) + 1), // + null terminator
-                       name: s.sym.Name,
+                       size: uint16(len(sym.Name) + 1), // + null terminator
+                       name: sym.Name,
                }
                stlen += uint32(2 + ldstr.size) // 2 = sizeof ldstr.size
                symtab = append(symtab, lds)
@@ -1278,28 +1294,28 @@ func (f *xcoffFile) writeLdrScn(ctxt *Link, globalOff uint64) {
 
        /* Reloc */
        ep := ctxt.Syms.ROLookup(*flagEntrySymbol, 0)
-       ldr := &XcoffLdRel64{
+       xldr := &XcoffLdRel64{
                Lvaddr:  uint64(ep.Value),
                Lrtype:  0x3F00,
                Lrsecnm: f.getXCOFFscnum(ep.Sect),
                Lsymndx: 0,
        }
        off += 16
-       reloctab = append(reloctab, ldr)
+       reloctab = append(reloctab, xldr)
 
        off += uint64(16 * len(f.loaderReloc))
        for _, r := range f.loaderReloc {
-               ldr = &XcoffLdRel64{
+               xldr = &XcoffLdRel64{
                        Lvaddr:  uint64(r.sym.Value + int64(r.rel.Off)),
                        Lrtype:  r.rtype,
                        Lsymndx: r.symndx,
                }
 
                if r.sym.Sect != nil {
-                       ldr.Lrsecnm = f.getXCOFFscnum(r.sym.Sect)
+                       xldr.Lrsecnm = f.getXCOFFscnum(r.sym.Sect)
                }
 
-               reloctab = append(reloctab, ldr)
+               reloctab = append(reloctab, xldr)
        }
 
        off += uint64(16 * len(dynimpreloc))
@@ -1672,9 +1688,12 @@ func xcoffCreateExportFile(ctxt *Link) (fname string) {
                if !s.Attr.CgoExport() {
                        continue
                }
-               if !strings.HasPrefix(s.Extname(), "_cgoexp_") {
+               if !strings.HasPrefix(s.Extname(), "._cgoexp_") {
                        continue
                }
+               if s.Version != 0 {
+                       continue // Only export version 0 symbols. See the comment in doxcoff.
+               }
 
                // Retrieve the name of the initial symbol
                // exported by cgo.
index 2eabefd4fb9e2d7ee57acdca682fedcf35e6a07b..0d409400938e3cee80faeb15ccdd88f3f61c6530 100644 (file)
@@ -463,7 +463,7 @@ func parseArmAttributes(e binary.ByteOrder, data []byte) (found bool, ehdrFlags
 // TODO: find a better place for this logic.
 func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, pkg string, length int64, pn string, initEhdrFlags uint32) (textp []loader.Sym, ehdrFlags uint32, err error) {
        newSym := func(name string, version int) loader.Sym {
-               return l.CreateExtSym(name)
+               return l.CreateStaticSym(name)
        }
        lookup := func(name string, version int) loader.Sym {
                return l.LookupOrCreateSym(name, version)
index 03c64839bedd7af89dcc3ab5d70fc0537161efb6..7e8469f501e7dd254906619e076fce4006e50eba 100644 (file)
@@ -904,6 +904,10 @@ func (l *Loader) SetAttrCgoExportStatic(i Sym, v bool) {
        }
 }
 
+func (l *Loader) AttrCgoExport(i Sym) bool {
+       return l.AttrCgoExportDynamic(i) || l.AttrCgoExportStatic(i)
+}
+
 // AttrReadOnly returns true for a symbol whose underlying data
 // is stored via a read-only mmap.
 func (l *Loader) AttrReadOnly(i Sym) bool {
@@ -2351,8 +2355,8 @@ func (l *Loader) migrateAttributes(src Sym, dst *sym.Symbol) {
        dst.Attr.Set(sym.AttrSubSymbol, dst.Outer != nil)
 
        // Copy over dynimplib, dynimpvers, extname.
-       if l.SymExtname(src) != "" {
-               dst.SetExtname(l.SymExtname(src))
+       if name, ok := l.extname[src]; ok {
+               dst.SetExtname(name)
        }
        if l.SymDynimplib(src) != "" {
                dst.SetDynimplib(l.SymDynimplib(src))
@@ -2377,7 +2381,13 @@ func (l *Loader) migrateAttributes(src Sym, dst *sym.Symbol) {
 
 // CreateExtSym creates a new external symbol with the specified name
 // without adding it to any lookup tables, returning a Sym index for it.
-func (l *Loader) CreateExtSym(name string) Sym {
+func (l *Loader) CreateExtSym(name string, ver int) Sym {
+       return l.newExtSym(name, ver)
+}
+
+// CreateStaticSym creates a new static symbol with the specified name
+// without adding it to any lookup tables, returning a Sym index for it.
+func (l *Loader) CreateStaticSym(name string) Sym {
        // Assign a new unique negative version -- this is to mark the
        // symbol so that it can be skipped when ExtractSymbols is adding
        // ext syms to the sym.Symbols hash.
index fba4bf8848ae53becac46b6c9d4cbad9d4ec3c0e..b384c752f4caec18c6818b7b03c350736f63a427 100644 (file)
@@ -52,9 +52,9 @@ func TestAddMaterializedSymbol(t *testing.T) {
                t.Fatalf("LookupOrCreateSym failed for go.info.type.uint8")
        }
        // Create a nameless symbol
-       es3 := ldr.CreateExtSym("")
+       es3 := ldr.CreateStaticSym("")
        if es3 == 0 {
-               t.Fatalf("CreateExtSym failed for nameless sym")
+               t.Fatalf("CreateStaticSym failed for nameless sym")
        }
 
        // Grab symbol builder pointers
index aeaec8b7b04f377072862e2b34216904a2616b97..c26646cbdb6b5eedc433a96a151d166fdec2f1bc 100644 (file)
@@ -23,7 +23,7 @@ type SymbolBuilder struct {
 // an entirely new symbol.
 func (l *Loader) MakeSymbolBuilder(name string) *SymbolBuilder {
        // for now assume that any new sym is intended to be static
-       symIdx := l.CreateExtSym(name)
+       symIdx := l.CreateStaticSym(name)
        if l.Syms[symIdx] != nil {
                panic("can't build if sym.Symbol already present")
        }
@@ -86,6 +86,7 @@ func (sb *SymbolBuilder) Dynimplib() string      { return sb.l.SymDynimplib(sb.s
 func (sb *SymbolBuilder) Dynimpvers() string     { return sb.l.SymDynimpvers(sb.symIdx) }
 func (sb *SymbolBuilder) SubSym() Sym            { return sb.l.SubSym(sb.symIdx) }
 func (sb *SymbolBuilder) GoType() Sym            { return sb.l.SymGoType(sb.symIdx) }
+func (sb *SymbolBuilder) VisibilityHidden() bool { return sb.l.AttrVisibilityHidden(sb.symIdx) }
 
 // Setters for symbol properties.
 
@@ -103,6 +104,9 @@ func (sb *SymbolBuilder) SetDynimpvers(value string) { sb.l.SetSymDynimpvers(sb.
 func (sb *SymbolBuilder) SetPlt(value int32)         { sb.l.SetPlt(sb.symIdx, value) }
 func (sb *SymbolBuilder) SetGot(value int32)         { sb.l.SetGot(sb.symIdx, value) }
 func (sb *SymbolBuilder) SetSpecial(value bool)      { sb.l.SetAttrSpecial(sb.symIdx, value) }
+func (sb *SymbolBuilder) SetVisibilityHidden(value bool) {
+       sb.l.SetAttrVisibilityHidden(sb.symIdx, value)
+}
 
 func (sb *SymbolBuilder) SetNotInSymbolTable(value bool) {
        sb.l.SetAttrNotInSymbolTable(sb.symIdx, value)
@@ -314,6 +318,10 @@ func (sb *SymbolBuilder) AddAddrPlus4(arch *sys.Arch, tgt Sym, add int64) int64
        return sb.addSymRef(tgt, add, objabi.R_ADDR, 4)
 }
 
+func (sb *SymbolBuilder) AddAddr(arch *sys.Arch, tgt Sym) int64 {
+       return sb.AddAddrPlus(arch, tgt, 0)
+}
+
 func (sb *SymbolBuilder) AddPCRelPlus(arch *sys.Arch, tgt Sym, add int64) int64 {
        sb.setReachable()
        return sb.addSymRef(tgt, add, objabi.R_PCREL, 4)