]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: use correct alignment for type descriptors on AIX
authorIan Lance Taylor <iant@golang.org>
Sat, 31 Jan 2026 03:06:19 +0000 (19:06 -0800)
committerGopher Robot <gobot@golang.org>
Fri, 6 Feb 2026 23:30:41 +0000 (15:30 -0800)
CL 724261 changed the linker to put all type descriptors that
are used for typelinks in a single list. This caused trouble on AIX when
linking externally, because the AIX linker aligns symbols individually,
rather than honoring the layout of the object file generated by the
internal linker.

I fixed internal linking problems with CL 740220,
but that just made things worse for the external linker.

This CL rolls back 740220, and adds commentary.
With this CL we force a smaller alignment for type descriptors,
use the same alignment for runtime.types and type:*,
and use a consistent size for runtime.types in all cases.

With this change all the type descriptor related code
passes again on AIX, except for the new TestTypePlacement test
which I will fix in a followup CL.

Fixes #77400

Change-Id: I9f25847eb0588001cb4ce453f211a655400d6a59
Reviewed-on: https://go-review.googlesource.com/c/go/+/740820
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Ian Lance Taylor <iant@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/symtab.go
src/cmd/link/internal/ld/xcoff.go
src/runtime/type.go

index a045ff5eeacf7b61cdcfb7afc4cdc9fb63497bf6..de9e9ea59ee768f50e69569f80d055e971b605b7 100644 (file)
@@ -1469,6 +1469,8 @@ func checkSectSize(sect *sym.Section) {
 
 // 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 @@ func fixZeroSizedSymbols(ctxt *Link) {
        // 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 @@ func fixZeroSizedSymbols(ctxt *Link) {
        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)
@@ -2189,11 +2206,19 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
        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++
                }
 
@@ -2351,6 +2376,10 @@ func (state *dodataState) dodataSect(ctxt *Link, symn sym.SymKind, syms []loader
                                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)
index 142fb15785d7fde680ac729c8947f6093ffe3615..b88cfd33866247c34d21caa87b492de503a573cf 100644 (file)
@@ -528,6 +528,15 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
                        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)
+                               }
+                       }
                }
        }
 
index 8edd4ccad880759295139f17e5e79d48509b49df..e263500eab969d991d80b9f69fb0308052c2d487 100644 (file)
@@ -586,14 +586,9 @@ func xcoffUpdateOuterSize(ctxt *Link, size int64, stype sym.SymKind) {
        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:
index 78018fd9a88e45b7759d0bfcb6451d01a258f1e2..82ac5120bb6632f09f066a1feb311b5132516b11 100644 (file)
@@ -520,6 +520,11 @@ func moduleTypelinks(md *moduledata) []*_type {
 
        // 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 @@ func moduleTypelinks(md *moduledata) []*_type {
                // 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)
                }