]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: refactor some of dodata
authorJeremy Faller <jeremy@golang.org>
Mon, 9 Mar 2020 14:35:31 +0000 (10:35 -0400)
committerJeremy Faller <jeremy@golang.org>
Tue, 24 Mar 2020 16:00:49 +0000 (16:00 +0000)
This is a non-functional change, just moving things around, making
dodata a more approachable piece of code.

Change-Id: I06fa047cbef2313040a31998fa8d242ccb2fedea
Reviewed-on: https://go-review.googlesource.com/c/go/+/222662
Run-TryBot: Jeremy Faller <jeremy@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/target.go

index bef049d7b2654ee29a22eb3bc9720c4b65e77b2f..603630c6bc9f95e850851e8334d9f6c5962bc16d 100644 (file)
@@ -1155,71 +1155,135 @@ func checkdatsize(ctxt *Link, datsize int64, symn sym.SymKind) {
        }
 }
 
-// datap is a collection of reachable data symbols in address order.
-// Generated by dodata.
-var datap []*sym.Symbol
+// fixZeroSizedSymbols gives a few special symbols with zero size some space.
+func fixZeroSizedSymbols(ctxt *Link) {
+       // The values in moduledata are filled out by relocations
+       // pointing to the addresses of these special symbols.
+       // Typically these symbols have no size and are not laid
+       // out with their matching section.
+       //
+       // However on darwin, dyld will find the special symbol
+       // in the first loaded module, even though it is local.
+       //
+       // (An hypothesis, formed without looking in the dyld sources:
+       // these special symbols have no size, so their address
+       // matches a real symbol. The dynamic linker assumes we
+       // want the normal symbol with the same address and finds
+       // it in the other module.)
+       //
+       // To work around this we lay out the symbls whose
+       // addresses are vital for multi-module programs to work
+       // as normal symbols, and give them a little size.
+       //
+       // On AIX, as all DATA sections are merged together, ld might not put
+       // these symbols at the beginning of their respective section if there
+       // aren't real symbols, their alignment might not match the
+       // first symbol alignment. Therefore, there are explicitly put at the
+       // beginning of their section with the same alignment.
+       if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
+               return
+       }
 
-func (ctxt *Link) dodata() {
-       if (ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
-               // The values in moduledata are filled out by relocations
-               // pointing to the addresses of these special symbols.
-               // Typically these symbols have no size and are not laid
-               // out with their matching section.
-               //
-               // However on darwin, dyld will find the special symbol
-               // in the first loaded module, even though it is local.
-               //
-               // (An hypothesis, formed without looking in the dyld sources:
-               // these special symbols have no size, so their address
-               // matches a real symbol. The dynamic linker assumes we
-               // want the normal symbol with the same address and finds
-               // it in the other module.)
-               //
-               // To work around this we lay out the symbls whose
-               // addresses are vital for multi-module programs to work
-               // as normal symbols, and give them a little size.
-               //
-               // On AIX, as all DATA sections are merged together, ld might not put
-               // these symbols at the beginning of their respective section if there
-               // aren't real symbols, their alignment might not match the
-               // first symbol alignment. Therefore, there are explicitly put at the
-               // beginning of their section with the same alignment.
-               bss := ctxt.Syms.Lookup("runtime.bss", 0)
-               bss.Size = 8
-               bss.Attr.Set(sym.AttrSpecial, false)
-
-               ctxt.Syms.Lookup("runtime.ebss", 0).Attr.Set(sym.AttrSpecial, false)
-
-               data := ctxt.Syms.Lookup("runtime.data", 0)
-               data.Size = 8
-               data.Attr.Set(sym.AttrSpecial, false)
-
-               edata := ctxt.Syms.Lookup("runtime.edata", 0)
-               edata.Attr.Set(sym.AttrSpecial, false)
-               if ctxt.HeadType == objabi.Haix {
-                       // XCOFFTOC symbols are part of .data section.
-                       edata.Type = sym.SXCOFFTOC
-               }
+       bss := ctxt.Syms.Lookup("runtime.bss", 0)
+       bss.Size = 8
+       bss.Attr.Set(sym.AttrSpecial, false)
 
-               types := ctxt.Syms.Lookup("runtime.types", 0)
-               types.Type = sym.STYPE
-               types.Size = 8
-               types.Attr.Set(sym.AttrSpecial, false)
+       ctxt.Syms.Lookup("runtime.ebss", 0).Attr.Set(sym.AttrSpecial, false)
 
-               etypes := ctxt.Syms.Lookup("runtime.etypes", 0)
-               etypes.Type = sym.SFUNCTAB
-               etypes.Attr.Set(sym.AttrSpecial, false)
+       data := ctxt.Syms.Lookup("runtime.data", 0)
+       data.Size = 8
+       data.Attr.Set(sym.AttrSpecial, false)
 
-               if ctxt.HeadType == objabi.Haix {
-                       rodata := ctxt.Syms.Lookup("runtime.rodata", 0)
-                       rodata.Type = sym.SSTRING
-                       rodata.Size = 8
-                       rodata.Attr.Set(sym.AttrSpecial, false)
+       edata := ctxt.Syms.Lookup("runtime.edata", 0)
+       edata.Attr.Set(sym.AttrSpecial, false)
+       if ctxt.HeadType == objabi.Haix {
+               // XCOFFTOC symbols are part of .data section.
+               edata.Type = sym.SXCOFFTOC
+       }
 
-                       ctxt.Syms.Lookup("runtime.erodata", 0).Attr.Set(sym.AttrSpecial, false)
+       types := ctxt.Syms.Lookup("runtime.types", 0)
+       types.Type = sym.STYPE
+       types.Size = 8
+       types.Attr.Set(sym.AttrSpecial, false)
 
+       etypes := ctxt.Syms.Lookup("runtime.etypes", 0)
+       etypes.Type = sym.SFUNCTAB
+       etypes.Attr.Set(sym.AttrSpecial, false)
+
+       if ctxt.HeadType == objabi.Haix {
+               rodata := ctxt.Syms.Lookup("runtime.rodata", 0)
+               rodata.Type = sym.SSTRING
+               rodata.Size = 8
+               rodata.Attr.Set(sym.AttrSpecial, false)
+
+               ctxt.Syms.Lookup("runtime.erodata", 0).Attr.Set(sym.AttrSpecial, false)
+       }
+}
+
+// makeRelroForSharedLib creates a section of readonly data if necessary.
+func makeRelroForSharedLib(target *Link, data *[sym.SXREF][]*sym.Symbol) {
+       if !target.UseRelro() {
+               return
+       }
+
+       // "read only" data with relocations needs to go in its own section
+       // when building a shared library. We do this by boosting objects of
+       // type SXXX with relocations to type SXXXRELRO.
+       for _, symnro := range sym.ReadOnly {
+               symnrelro := sym.RelROMap[symnro]
+
+               ro := []*sym.Symbol{}
+               relro := data[symnrelro]
+
+               for _, s := range data[symnro] {
+                       isRelro := len(s.R) > 0
+                       switch s.Type {
+                       case sym.STYPE, sym.STYPERELRO, sym.SGOFUNCRELRO:
+                               // Symbols are not sorted yet, so it is possible
+                               // that an Outer symbol has been changed to a
+                               // relro Type before it reaches here.
+                               isRelro = true
+                       case sym.SFUNCTAB:
+                               if target.IsAIX() && s.Name == "runtime.etypes" {
+                                       // runtime.etypes must be at the end of
+                                       // the relro datas.
+                                       isRelro = true
+                               }
+                       }
+                       if isRelro {
+                               s.Type = symnrelro
+                               if s.Outer != nil {
+                                       s.Outer.Type = s.Type
+                               }
+                               relro = append(relro, s)
+                       } else {
+                               ro = append(ro, s)
+                       }
                }
+
+               // Check that we haven't made two symbols with the same .Outer into
+               // different types (because references two symbols with non-nil Outer
+               // become references to the outer symbol + offset it's vital that the
+               // symbol and the outer end up in the same section).
+               for _, s := range relro {
+                       if s.Outer != nil && s.Outer.Type != s.Type {
+                               Errorf(s, "inconsistent types for symbol and its Outer %s (%v != %v)",
+                                       s.Outer.Name, s.Type, s.Outer.Type)
+                       }
+               }
+
+               data[symnro] = ro
+               data[symnrelro] = relro
        }
+}
+
+// datap is a collection of reachable data symbols in address order.
+// Generated by dodata.
+var datap []*sym.Symbol
+
+func (ctxt *Link) dodata() {
+       // Give zeros sized symbols space if necessary.
+       fixZeroSizedSymbols(ctxt)
 
        // Collect data symbols by type into data.
        var data [sym.SXREF][]*sym.Symbol
@@ -1244,57 +1308,8 @@ func (ctxt *Link) dodata() {
        }
        dynreloc(ctxt, &data)
 
-       if ctxt.UseRelro() {
-               // "read only" data with relocations needs to go in its own section
-               // when building a shared library. We do this by boosting objects of
-               // type SXXX with relocations to type SXXXRELRO.
-               for _, symnro := range sym.ReadOnly {
-                       symnrelro := sym.RelROMap[symnro]
-
-                       ro := []*sym.Symbol{}
-                       relro := data[symnrelro]
-
-                       for _, s := range data[symnro] {
-                               isRelro := len(s.R) > 0
-                               switch s.Type {
-                               case sym.STYPE, sym.STYPERELRO, sym.SGOFUNCRELRO:
-                                       // Symbols are not sorted yet, so it is possible
-                                       // that an Outer symbol has been changed to a
-                                       // relro Type before it reaches here.
-                                       isRelro = true
-                               case sym.SFUNCTAB:
-                                       if ctxt.HeadType == objabi.Haix && s.Name == "runtime.etypes" {
-                                               // runtime.etypes must be at the end of
-                                               // the relro datas.
-                                               isRelro = true
-                                       }
-                               }
-                               if isRelro {
-                                       s.Type = symnrelro
-                                       if s.Outer != nil {
-                                               s.Outer.Type = s.Type
-                                       }
-                                       relro = append(relro, s)
-                               } else {
-                                       ro = append(ro, s)
-                               }
-                       }
-
-                       // Check that we haven't made two symbols with the same .Outer into
-                       // different types (because references two symbols with non-nil Outer
-                       // become references to the outer symbol + offset it's vital that the
-                       // symbol and the outer end up in the same section).
-                       for _, s := range relro {
-                               if s.Outer != nil && s.Outer.Type != s.Type {
-                                       Errorf(s, "inconsistent types for symbol and its Outer %s (%v != %v)",
-                                               s.Outer.Name, s.Type, s.Outer.Type)
-                               }
-                       }
-
-                       data[symnro] = ro
-                       data[symnrelro] = relro
-               }
-       }
+       // Move any RO data with relocations to a separate section.
+       makeRelroForSharedLib(ctxt, &data)
 
        // Sort symbols.
        var dataMaxAlign [sym.SXREF]int32
index e2051035c9c03c68acfee9390099be66b4717476..1537bc662bc57d84c99f369965b07f8bd9406ba2 100644 (file)
@@ -251,17 +251,6 @@ func (ctxt *Link) CanUsePlugins() bool {
        return ctxt.canUsePlugins
 }
 
-// UseRelro reports whether to make use of "read only relocations" aka
-// relro.
-func (ctxt *Link) UseRelro() bool {
-       switch ctxt.BuildMode {
-       case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePIE, BuildModePlugin:
-               return ctxt.IsELF || ctxt.HeadType == objabi.Haix
-       default:
-               return ctxt.linkShared || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal)
-       }
-}
-
 var (
        dynexp          []*sym.Symbol
        dynlib          []string
index 197c4122142b7e4370a0d6bbbd32b0c44f8bd602..95f6ca17abd5f0ccc6a58afd0fd612f878ce72ee 100644 (file)
@@ -64,6 +64,17 @@ func (t *Target) IsDynlinkingGo() bool {
        return t.IsShared() || t.IsSharedGoLink() || t.IsPlugin() || t.CanUsePlugins()
 }
 
+// UseRelro reports whether to make use of "read only relocations" aka
+// relro.
+func (t *Target) UseRelro() bool {
+       switch t.BuildMode {
+       case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePIE, BuildModePlugin:
+               return t.IsELF || t.HeadType == objabi.Haix
+       default:
+               return t.linkShared || (t.HeadType == objabi.Haix && t.LinkMode == LinkExternal)
+       }
+}
+
 //
 // Processor functions
 //