]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj: index pcdata symbols in NumberSyms
authorCherry Mui <cherryyz@google.com>
Mon, 27 Sep 2021 19:35:46 +0000 (15:35 -0400)
committerCherry Mui <cherryyz@google.com>
Tue, 28 Sep 2021 15:25:40 +0000 (15:25 +0000)
When writing an object file, most symbols are indexed in
NumberSyms. Currently, pcdata symbols are indexed late and
separately. This is not really necessary, as pcdata symbols
already exist at the time of NumberSyms. Just do it there.

As pcdata symbols are laid out in the pclntab in a special way at
link time, distinguish them from other symbols in the content
hash. (In the old code this was partly achieved by indexing them
late.)

Change-Id: Ie9e721382b0af2cfb39350d031e2e66d79095a3c
Reviewed-on: https://go-review.googlesource.com/c/go/+/352611
Trust: Cherry Mui <cherryyz@google.com>
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
src/cmd/internal/obj/link.go
src/cmd/internal/obj/objfile.go
src/cmd/internal/obj/pcln.go
src/cmd/internal/obj/sym.go

index 9be173ff98b52f55d421a8825d5e3118e8a9ccc1..82ff5994d1b31cc2357f729ec0c0af1a83f06f4d 100644 (file)
@@ -700,6 +700,9 @@ const (
        // convert between ABI0 and ABIInternal calling conventions.
        AttrABIWrapper
 
+       // IsPcdata indicates this is a pcdata symbol.
+       AttrPcdata
+
        // attrABIBase is the value at which the ABI is encoded in
        // Attribute. This must be last; all bits after this are
        // assumed to be an ABI value.
@@ -727,6 +730,7 @@ func (a *Attribute) Indexed() bool            { return a.load()&AttrIndexed != 0
 func (a *Attribute) UsedInIface() bool        { return a.load()&AttrUsedInIface != 0 }
 func (a *Attribute) ContentAddressable() bool { return a.load()&AttrContentAddressable != 0 }
 func (a *Attribute) ABIWrapper() bool         { return a.load()&AttrABIWrapper != 0 }
+func (a *Attribute) IsPcdata() bool           { return a.load()&AttrPcdata != 0 }
 
 func (a *Attribute) Set(flag Attribute, value bool) {
        for {
index 1a8a9635d6029bc99165abb28b78e3ecfc941ca4..030a02b4992db68053bfb28e8bc8404bba3880a3 100644 (file)
@@ -391,7 +391,9 @@ func (w *writer) Hash(s *LSym) {
 // TODO: instead of duplicating them, have the compiler decide where symbols go.
 func contentHashSection(s *LSym) byte {
        name := s.Name
-       if strings.HasPrefix(name, "type.") {
+       if s.IsPcdata() {
+               return 'P'
+       } else if strings.HasPrefix(name, "type.") {
                return 'T'
        }
        return 0
@@ -655,16 +657,6 @@ func nAuxSym(s *LSym) int {
 func genFuncInfoSyms(ctxt *Link) {
        infosyms := make([]*LSym, 0, len(ctxt.Text))
        hashedsyms := make([]*LSym, 0, 4*len(ctxt.Text))
-       preparePcSym := func(s *LSym) *LSym {
-               if s == nil {
-                       return s
-               }
-               s.PkgIdx = goobj.PkgIdxHashed
-               s.SymIdx = int32(len(hashedsyms) + len(ctxt.hasheddefs))
-               s.Set(AttrIndexed, true)
-               hashedsyms = append(hashedsyms, s)
-               return s
-       }
        var b bytes.Buffer
        symidx := int32(len(ctxt.defs))
        for _, s := range ctxt.Text {
@@ -679,13 +671,13 @@ func genFuncInfoSyms(ctxt *Link) {
                        FuncFlag: fn.FuncFlag,
                }
                pc := &fn.Pcln
-               o.Pcsp = makeSymRef(preparePcSym(pc.Pcsp))
-               o.Pcfile = makeSymRef(preparePcSym(pc.Pcfile))
-               o.Pcline = makeSymRef(preparePcSym(pc.Pcline))
-               o.Pcinline = makeSymRef(preparePcSym(pc.Pcinline))
+               o.Pcsp = makeSymRef(pc.Pcsp)
+               o.Pcfile = makeSymRef(pc.Pcfile)
+               o.Pcline = makeSymRef(pc.Pcline)
+               o.Pcinline = makeSymRef(pc.Pcinline)
                o.Pcdata = make([]goobj.SymRef, len(pc.Pcdata))
                for i, pcSym := range pc.Pcdata {
-                       o.Pcdata[i] = makeSymRef(preparePcSym(pcSym))
+                       o.Pcdata[i] = makeSymRef(pcSym)
                }
                o.Funcdataoff = make([]uint32, len(pc.Funcdataoff))
                for i, x := range pc.Funcdataoff {
index 7af81335fb10f61be799c90f4b50d5ca4331cbae..42c4a2a9d98cbadf376054c3d282182f6eac32a1 100644 (file)
@@ -26,7 +26,7 @@ func funcpctab(ctxt *Link, func_ *LSym, desc string, valfunc func(*Link, *LSym,
        dst := []byte{}
        sym := &LSym{
                Type:      objabi.SRODATA,
-               Attribute: AttrContentAddressable,
+               Attribute: AttrContentAddressable | AttrPcdata,
        }
 
        if dbg {
@@ -337,7 +337,7 @@ func linkpcln(ctxt *Link, cursym *LSym) {
                        // use an empty symbol.
                        pcln.Pcdata[i] = &LSym{
                                Type:      objabi.SRODATA,
-                               Attribute: AttrContentAddressable,
+                               Attribute: AttrContentAddressable | AttrPcdata,
                        }
                } else {
                        pcln.Pcdata[i] = funcpctab(ctxt, cursym, "pctopcdata", pctopcdata, interface{}(uint32(i)))
index 6cd8bb3c3f7fbd5f9a55afaa252ef77e3764592f..a272c517b3b5dd6e2486b713b8a9ab30e655ab33 100644 (file)
@@ -201,7 +201,7 @@ func (ctxt *Link) NumberSyms() {
        ctxt.nonpkgdefs = []*LSym{}
 
        var idx, hashedidx, hashed64idx, nonpkgidx int32
-       ctxt.traverseSyms(traverseDefs, func(s *LSym) {
+       ctxt.traverseSyms(traverseDefs|traversePcdata, func(s *LSym) {
                // if Pkgpath is unknown, cannot hash symbols with relocations, as it
                // may reference named symbols whose names are not fully expanded.
                if s.ContentAddressable() && (ctxt.Pkgpath != "" || len(s.R) == 0) {
@@ -324,12 +324,18 @@ const (
        traverseDefs traverseFlag = 1 << iota
        traverseRefs
        traverseAux
+       traversePcdata
 
-       traverseAll = traverseDefs | traverseRefs | traverseAux
+       traverseAll = traverseDefs | traverseRefs | traverseAux | traversePcdata
 )
 
 // Traverse symbols based on flag, call fn for each symbol.
 func (ctxt *Link) traverseSyms(flag traverseFlag, fn func(*LSym)) {
+       fnNoNil := func(s *LSym) {
+               if s != nil {
+                       fn(s)
+               }
+       }
        lists := [][]*LSym{ctxt.Text, ctxt.Data}
        for _, list := range lists {
                for _, s := range list {
@@ -338,15 +344,11 @@ func (ctxt *Link) traverseSyms(flag traverseFlag, fn func(*LSym)) {
                        }
                        if flag&traverseRefs != 0 {
                                for _, r := range s.R {
-                                       if r.Sym != nil {
-                                               fn(r.Sym)
-                                       }
+                                       fnNoNil(r.Sym)
                                }
                        }
                        if flag&traverseAux != 0 {
-                               if s.Gotype != nil {
-                                       fn(s.Gotype)
-                               }
+                               fnNoNil(s.Gotype)
                                if s.Type == objabi.STEXT {
                                        f := func(parent *LSym, aux *LSym) {
                                                fn(aux)
@@ -354,6 +356,16 @@ func (ctxt *Link) traverseSyms(flag traverseFlag, fn func(*LSym)) {
                                        ctxt.traverseFuncAux(flag, s, f)
                                }
                        }
+                       if flag&traversePcdata != 0 && s.Type == objabi.STEXT {
+                               fi := s.Func().Pcln
+                               fnNoNil(fi.Pcsp)
+                               fnNoNil(fi.Pcfile)
+                               fnNoNil(fi.Pcline)
+                               fnNoNil(fi.Pcinline)
+                               for _, d := range fi.Pcdata {
+                                       fnNoNil(d)
+                               }
+                       }
                }
        }
 }