From d3631955d454a8cfc0b63065ef1cc4c8db64ae46 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Cl=C3=A9ment=20Chigot?= Date: Wed, 20 Feb 2019 15:54:11 +0100 Subject: [PATCH] cmd/link: set correct sizes for XCOFF outer symbols This commit fixes the size of outer symbols like type.*. Outer symbols cannot have a nil size on AIX or they will be removed by ld as long as all their sub-symbols. Change-Id: I68ff3ce5a3a034e3c3eb23431aba31245073cf20 Reviewed-on: https://go-review.googlesource.com/c/163999 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/cmd/link/internal/ld/data.go | 21 +++++++++++++ src/cmd/link/internal/ld/xcoff.go | 51 +++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index e72ad40ce9..46d85f003d 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -1475,6 +1475,7 @@ func (ctxt *Link) dodata() { } datsize = Rnd(datsize, int64(sect.Align)) for _, symn := range sym.ReadOnly { + symnStartValue := datsize for _, s := range data[symn] { datsize = aligndatsize(datsize, s) s.Sect = sect @@ -1483,6 +1484,13 @@ func (ctxt *Link) dodata() { datsize += s.Size } checkdatsize(ctxt, datsize, symn) + if ctxt.HeadType == objabi.Haix { + // Read-only symbols might be wrapped inside their outer + // symbol. + // XCOFF symbol table needs to know the size of + // these outer symbols. + xcoffUpdateOuterSize(ctxt, datsize-symnStartValue, symn) + } } sect.Length = uint64(datsize) - sect.Vaddr @@ -1557,6 +1565,7 @@ func (ctxt *Link) dodata() { datsize = Rnd(datsize, int64(sect.Align)) for _, symnro := range sym.ReadOnly { symn := sym.RelROMap[symnro] + symnStartValue := datsize for _, s := range data[symn] { datsize = aligndatsize(datsize, s) if s.Outer != nil && s.Outer.Sect != nil && s.Outer.Sect != sect { @@ -1568,6 +1577,13 @@ func (ctxt *Link) dodata() { datsize += s.Size } checkdatsize(ctxt, datsize, symn) + if ctxt.HeadType == objabi.Haix { + // Read-only symbols might be wrapped inside their outer + // symbol. + // XCOFF symbol table needs to know the size of + // these outer symbols. + xcoffUpdateOuterSize(ctxt, datsize-symnStartValue, symn) + } } sect.Length = uint64(datsize) - sect.Vaddr @@ -1601,6 +1617,11 @@ func (ctxt *Link) dodata() { } checkdatsize(ctxt, datsize, sym.SITABLINK) sect.Length = uint64(datsize) - sect.Vaddr + if ctxt.HeadType == objabi.Haix { + // Store .itablink size because its symbols are wrapped + // under an outer symbol: runtime.itablink. + xcoffUpdateOuterSize(ctxt, int64(sect.Length), sym.SITABLINK) + } /* gosymtab */ sect = addrelrosection(".gosymtab") diff --git a/src/cmd/link/internal/ld/xcoff.go b/src/cmd/link/internal/ld/xcoff.go index e565a3588d..188c7a5cff 100644 --- a/src/cmd/link/internal/ld/xcoff.go +++ b/src/cmd/link/internal/ld/xcoff.go @@ -529,8 +529,48 @@ type xcoffSymSrcFile struct { var ( currDwscnoff = make(map[string]uint64) // Needed to create C_DWARF symbols currSymSrcFile xcoffSymSrcFile + outerSymSize = make(map[string]int64) ) +// xcoffUpdateOuterSize stores the size of outer symbols in order to have it +// in the symbol table. +func xcoffUpdateOuterSize(ctxt *Link, size int64, stype sym.SymKind) { + if size == 0 { + return + } + + switch stype { + default: + Errorf(nil, "unknown XCOFF outer symbol for type %s", stype.String()) + case sym.SRODATA, sym.SRODATARELRO, sym.SFUNCTAB, sym.SSTRING: + // Nothing to do + case sym.STYPERELRO: + if ctxt.UseRelro() && (ctxt.BuildMode == BuildModeCArchive || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE) { + outerSymSize["typerel.*"] = size + return + } + fallthrough + case sym.STYPE: + if !ctxt.DynlinkingGo() { + outerSymSize["type.*"] = size + } + case sym.SGOSTRING: + outerSymSize["go.string.*"] = size + case sym.SGOFUNC: + if !ctxt.DynlinkingGo() { + outerSymSize["go.func.*"] = size + } + case sym.SGOFUNCRELRO: + outerSymSize["go.funcrel.*"] = size + case sym.SGCBITS: + outerSymSize["runtime.gcbits.*"] = size + case sym.SITABLINK: + outerSymSize["runtime.itablink"] = size + + } + +} + // addSymbol writes a symbol or an auxiliary symbol entry on ctxt.out. func (f *xcoffFile) addSymbol(sym xcoffSym) { f.symtabSym = append(f.symtabSym, sym) @@ -888,6 +928,17 @@ func putaixsym(ctxt *Link, x *sym.Symbol, str string, t SymbolType, addr int64, // It will be written in out file in Asmbxcoff, because it must be // at the very end, especially after relocation sections which needs symbols' index. func (f *xcoffFile) asmaixsym(ctxt *Link) { + // Get correct size for symbols wrapping others symbols like go.string.* + // sym.Size can be used directly as the symbols have already been written. + for name, size := range outerSymSize { + sym := ctxt.Syms.ROLookup(name, 0) + if sym == nil { + Errorf(nil, "unknown outer symbol with name %s", name) + } else { + sym.Size = size + } + } + genasmsym(ctxt, putaixsym) xfile.updatePreviousFile(ctxt, true) } -- 2.50.0