diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index 683df3b..e2f24d9 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -1469,6 +1469,8 @@
// fixZeroSizedSymbols gives a few special symbols with zero size some space.
func fixZeroSizedSymbols(ctxt *Link) {
+ ldr := ctxt.loader
+
// 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
@@ -1492,11 +1494,29 @@
// 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.
+
+ defineRuntimeTypes := func() {
+ types := ldr.CreateSymForUpdate("runtime.types", 0)
+ types.SetType(sym.STYPE)
+ types.SetSize(8)
+ types.SetAlign(int32(ctxt.Arch.PtrSize))
+ ldr.SetAttrSpecial(types.Sym(), false)
+ }
+
if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
+
+ // On AIX, below, we give runtime.types a size.
+ // That means that the type descriptors will actually
+ // follow runtime.types plus that size.
+ // To simplify matters for the runtime,
+ // always give runtime.types a size.
+ if ctxt.HeadType == objabi.Haix {
+ defineRuntimeTypes()
+ }
+
return
}
- ldr := ctxt.loader
bss := ldr.CreateSymForUpdate("runtime.bss", 0)
bss.SetSize(8)
ldr.SetAttrSpecial(bss.Sym(), false)
@@ -1530,10 +1550,7 @@
enoptrdata := ldr.CreateSymForUpdate("runtime.enoptrdata", 0)
ldr.SetAttrSpecial(enoptrdata.Sym(), false)
- types := ldr.CreateSymForUpdate("runtime.types", 0)
- types.SetType(sym.STYPE)
- types.SetSize(8)
- ldr.SetAttrSpecial(types.Sym(), false)
+ defineRuntimeTypes()
etypes := ldr.CreateSymForUpdate("runtime.etypes", 0)
etypes.SetType(sym.STYPE)
@@ -2182,11 +2199,19 @@
createRelroSect := func(name string, symn sym.SymKind) *sym.Section {
sect := state.allocateNamedDataSection(segRelro, genrelrosecname(name), []sym.SymKind{symn}, relroPerm)
- if symn == sym.STYPE {
+ if symn == sym.STYPE && ctxt.HeadType != objabi.Haix {
// Skip forward so that no type
// reference uses a zero offset.
// This is unlikely but possible in small
// programs with no other read-only data.
+ //
+ // Don't skip forward on AIX because the external
+ // linker, when used, will align symbols itself.
+ // The external linker won't know about this skip,
+ // and will mess up the constant offsets we need
+ // within the type section. On AIX we just live
+ // with the possibility of a broken program
+ // if there is no other read-only data.
state.datsize++
}
@@ -2344,6 +2369,10 @@
tail = s
continue
}
+ } else if ctxt.HeadType == objabi.Haix && ldr.SymName(s) == "runtime.types" {
+ // We always use runtime.types on AIX.
+ // See the comment in fixZeroSizedSymbols.
+ head = s
}
}
zerobase = ldr.Lookup("runtime.zerobase", 0)
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
index 142fb15..b88cfd3 100644
--- a/src/cmd/link/internal/ld/symtab.go
+++ b/src/cmd/link/internal/ld/symtab.go
@@ -528,6 +528,15 @@
if symtype != 0 {
ldr.SetCarrierSym(s, symtype)
}
+ if ctxt.HeadType == objabi.Haix {
+ // The default alignment is currently 0x20,
+ // which the AIX external linker doesn't
+ // seem to support. To get consistent
+ // alignment on AIX, force alignment to 8.
+ if symalign(ldr, s) > 8 {
+ ldr.SetSymAlign(s, 8)
+ }
+ }
}
}
diff --git a/src/cmd/link/internal/ld/xcoff.go b/src/cmd/link/internal/ld/xcoff.go
index 8edd4cc..e263500 100644
--- a/src/cmd/link/internal/ld/xcoff.go
+++ b/src/cmd/link/internal/ld/xcoff.go
@@ -586,14 +586,9 @@
case sym.SRODATA, sym.SRODATARELRO, sym.SSTRING:
// Nothing to do
case sym.STYPE:
- if ctxt.UseRelro() && (ctxt.BuildMode == BuildModeCArchive || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE) {
- return
- }
- if !ctxt.DynlinkingGo() {
- // runtime.types size must be removed, as it's a real symbol.
- tsize := ldr.SymSize(ldr.Lookup("runtime.types", 0))
- outerSymSize["type:*"] = size - tsize
- }
+ // runtime.types size must be removed, as it's a real symbol.
+ tsize := ldr.SymSize(ldr.Lookup("runtime.types", 0))
+ outerSymSize["type:*"] = size - tsize
case sym.SGOSTRING:
outerSymSize["go:string.*"] = size
case sym.SGOFUNC:
diff --git a/src/runtime/type.go b/src/runtime/type.go
index 78018fd..82ac512 100644
--- a/src/runtime/type.go
+++ b/src/runtime/type.go
@@ -520,6 +520,11 @@
// We have to increment by 1 to match the increment done in
// cmd/link/internal/data.go createRelroSect in allocateDataSections.
+ //
+ // We don't do that increment on AIX, but on AIX we need to adjust
+ // for the fact that the runtime.types symbol has a size of 8,
+ // and the type descriptors will follow that. This increment,
+ // followed by the forced alignment to 8, will do that.
td++
etypedesc := md.types + md.typedesclen
@@ -528,6 +533,9 @@
// 0x20 does not make sense.
if GOARCH == "arm" {
td = alignUp(td, 0x8)
+ } else if GOOS == "aix" {
+ // The alignment of 8 is forced in the linker on AIX.
+ td = alignUp(td, 0x8)
} else {
td = alignUp(td, 0x20)
}