1
0
mirror of https://github.com/golang/go synced 2024-11-11 22:10:22 -07:00

cmd/link: make symbol data writable before toc fixup

On ppc64le, we need to insert a load to restore the toc
pointer in R2 after calling into plt stubs. Sometimes the
symbol data is loaded into readonly memory. This is the
case when linking with the race detector code.

Likewise, add extra checks to ensure we can, and are
replacing a nop.

Change-Id: Iea9d9ee7a5ba0f4ce285f4d0422823de1c037cb7
Reviewed-on: https://go-review.googlesource.com/c/go/+/304430
Run-TryBot: Paul Murphy <murp@ibm.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Lynn Boger <laboger@linux.vnet.ibm.com>
This commit is contained in:
Paul E. Murphy 2021-03-23 15:40:54 -05:00 committed by Lynn Boger
parent 4d66d77cd2
commit 82a1e0f9d3

View File

@ -121,16 +121,21 @@ func genplt(ctxt *ld.Link, ldr *loader.Loader) {
// Update the relocation to use the call stub
r.SetSym(stub.Sym())
// make sure the data is writeable
if ldr.AttrReadOnly(s) {
panic("can't write to read-only sym data")
}
// Make the symbol writeable so we can fixup toc.
su := ldr.MakeSymbolUpdater(s)
su.MakeWritable()
p := su.Data()
// Restore TOC after bl. The compiler put a
// nop here for us to overwrite.
sp := ldr.Data(s)
// Check for toc restore slot (a nop), and replace with toc restore.
var nop uint32
if len(p) >= int(r.Off()+8) {
nop = ctxt.Arch.ByteOrder.Uint32(p[r.Off()+4:])
}
if nop != 0x60000000 {
ldr.Errorf(s, "Symbol %s is missing toc restoration slot at offset %d", ldr.SymName(s), r.Off()+4)
}
const o1 = 0xe8410018 // ld r2,24(r1)
ctxt.Arch.ByteOrder.PutUint32(sp[r.Off()+4:], o1)
ctxt.Arch.ByteOrder.PutUint32(p[r.Off()+4:], o1)
}
}
// Put call stubs at the beginning (instead of the end).