1
0
mirror of https://github.com/golang/go synced 2024-11-23 10:20:03 -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 // Update the relocation to use the call stub
r.SetSym(stub.Sym()) r.SetSym(stub.Sym())
// make sure the data is writeable // Make the symbol writeable so we can fixup toc.
if ldr.AttrReadOnly(s) { su := ldr.MakeSymbolUpdater(s)
panic("can't write to read-only sym data") su.MakeWritable()
} p := su.Data()
// Restore TOC after bl. The compiler put a // Check for toc restore slot (a nop), and replace with toc restore.
// nop here for us to overwrite. var nop uint32
sp := ldr.Data(s) 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) 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). // Put call stubs at the beginning (instead of the end).