1
0
mirror of https://github.com/golang/go synced 2024-09-30 10:28:33 -06:00

[dev.link] cmd/link: fix bugs in setArchSyms

The code in setArchsyms that sets up TOC symbols was buggy; it was
kicking in only for aix-ppc64 and not linux-ppc64. These symbols are
required for both ABIs, so change the guard in question from
"ctx.IsAIX()" to "ctxt.IsPPC64()". Also, the code to create versioned
".TOC." syms was not passing the correct symbol version to the loader
(now fixed).

Change-Id: I356071e528beadad20f61d067059eaf26f06e06b
Reviewed-on: https://go-review.googlesource.com/c/go/+/227257
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Than McIntosh 2020-04-05 12:40:20 -04:00
parent 587faf67d7
commit 60baf83a82

View File

@ -150,19 +150,24 @@ type ArchSyms struct {
const BeforeLoadlibFull = 1
const AfterLoadlibFull = 2
func (ctxt *Link) mkArchSym(which int, name string, ls *loader.Sym, ss **sym.Symbol) {
// mkArchSym is a helper for setArchSyms, invoked once before loadlibfull
// and once after. On the first call it creates a loader.Sym with the
// specified name, and on the second call a corresponding sym.Symbol.
func (ctxt *Link) mkArchSym(which int, name string, ver int, ls *loader.Sym, ss **sym.Symbol) {
if which == BeforeLoadlibFull {
*ls = ctxt.loader.LookupOrCreateSym(name, 0)
*ls = ctxt.loader.LookupOrCreateSym(name, ver)
} else {
*ss = ctxt.loader.Syms[*ls]
}
}
func (ctxt *Link) mkArchSymVec(which int, name string, i int, ls []loader.Sym, ss []*sym.Symbol) {
// mkArchVecSym is similar to setArchSyms, but operates on elements within
// a slice, where each element corresponds to some symbol version.
func (ctxt *Link) mkArchSymVec(which int, name string, ver int, ls []loader.Sym, ss []*sym.Symbol) {
if which == BeforeLoadlibFull {
ls[i] = ctxt.loader.LookupOrCreateSym(name, 0)
} else {
ss[i] = ctxt.loader.Syms[ls[i]]
ls[ver] = ctxt.loader.LookupOrCreateSym(name, ver)
} else if ls[ver] != 0 {
ss[ver] = ctxt.loader.Syms[ls[ver]]
}
}
@ -173,15 +178,15 @@ func (ctxt *Link) setArchSyms(which int) {
if which != BeforeLoadlibFull && which != AfterLoadlibFull {
panic("internal error")
}
ctxt.mkArchSym(which, ".got", &ctxt.GOT2, &ctxt.GOT)
ctxt.mkArchSym(which, ".plt", &ctxt.PLT2, &ctxt.PLT)
ctxt.mkArchSym(which, ".got.plt", &ctxt.GOTPLT2, &ctxt.GOTPLT)
ctxt.mkArchSym(which, ".dynamic", &ctxt.Dynamic2, &ctxt.Dynamic)
ctxt.mkArchSym(which, ".dynsym", &ctxt.DynSym2, &ctxt.DynSym)
ctxt.mkArchSym(which, ".dynstr", &ctxt.DynStr2, &ctxt.DynStr)
ctxt.mkArchSym(which, ".got", 0, &ctxt.GOT2, &ctxt.GOT)
ctxt.mkArchSym(which, ".plt", 0, &ctxt.PLT2, &ctxt.PLT)
ctxt.mkArchSym(which, ".got.plt", 0, &ctxt.GOTPLT2, &ctxt.GOTPLT)
ctxt.mkArchSym(which, ".dynamic", 0, &ctxt.Dynamic2, &ctxt.Dynamic)
ctxt.mkArchSym(which, ".dynsym", 0, &ctxt.DynSym2, &ctxt.DynSym)
ctxt.mkArchSym(which, ".dynstr", 0, &ctxt.DynStr2, &ctxt.DynStr)
if ctxt.IsAIX() {
ctxt.mkArchSym(which, "TOC", &ctxt.TOC2, &ctxt.TOC)
if ctxt.IsPPC64() {
ctxt.mkArchSym(which, "TOC", 0, &ctxt.TOC2, &ctxt.TOC)
// NB: note the +2 below for DotTOC2 compared to the +1 for
// DocTOC. This is because loadlibfull() creates an additional
@ -198,20 +203,18 @@ func (ctxt *Link) setArchSyms(which int) {
if i >= 2 && i < sym.SymVerStatic { // these versions are not used currently
continue
}
if ctxt.DotTOC2[i] != 0 {
ctxt.mkArchSymVec(which, ".TOC.", i, ctxt.DotTOC2, ctxt.DotTOC)
}
ctxt.mkArchSymVec(which, ".TOC.", i, ctxt.DotTOC2, ctxt.DotTOC)
}
}
if ctxt.IsElf() {
ctxt.mkArchSym(which, ".rel", &ctxt.Rel2, &ctxt.Rel)
ctxt.mkArchSym(which, ".rela", &ctxt.Rela2, &ctxt.Rela)
ctxt.mkArchSym(which, ".rel.plt", &ctxt.RelPLT2, &ctxt.RelPLT)
ctxt.mkArchSym(which, ".rela.plt", &ctxt.RelaPLT2, &ctxt.RelaPLT)
ctxt.mkArchSym(which, ".rel", 0, &ctxt.Rel2, &ctxt.Rel)
ctxt.mkArchSym(which, ".rela", 0, &ctxt.Rela2, &ctxt.Rela)
ctxt.mkArchSym(which, ".rel.plt", 0, &ctxt.RelPLT2, &ctxt.RelPLT)
ctxt.mkArchSym(which, ".rela.plt", 0, &ctxt.RelaPLT2, &ctxt.RelaPLT)
}
if ctxt.IsDarwin() {
ctxt.mkArchSym(which, ".linkedit.got", &ctxt.LinkEditGOT2, &ctxt.LinkEditGOT)
ctxt.mkArchSym(which, ".linkedit.plt", &ctxt.LinkEditPLT2, &ctxt.LinkEditPLT)
ctxt.mkArchSym(which, ".linkedit.got", 0, &ctxt.LinkEditGOT2, &ctxt.LinkEditGOT)
ctxt.mkArchSym(which, ".linkedit.plt", 0, &ctxt.LinkEditPLT2, &ctxt.LinkEditPLT)
}
}