1
0
mirror of https://github.com/golang/go synced 2024-11-17 02:14:42 -07:00

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 <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Clément Chigot 2019-02-20 15:54:11 +01:00 committed by Ian Lance Taylor
parent 2deda8792a
commit d3631955d4
2 changed files with 72 additions and 0 deletions

View File

@ -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")

View File

@ -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)
}