}
}
-// 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
}
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