From 82a1e0f9d3e47ae7792cb857e950abc7103e9f39 Mon Sep 17 00:00:00 2001 From: "Paul E. Murphy" Date: Tue, 23 Mar 2021 15:40:54 -0500 Subject: [PATCH] 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 Reviewed-by: Cherry Zhang Reviewed-by: Lynn Boger TryBot-Result: Go Bot Trust: Lynn Boger --- src/cmd/link/internal/ppc64/asm.go | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go index aa2532ad37..e8e258a1f3 100644 --- a/src/cmd/link/internal/ppc64/asm.go +++ b/src/cmd/link/internal/ppc64/asm.go @@ -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() + + // 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) } - - // Restore TOC after bl. The compiler put a - // nop here for us to overwrite. - sp := ldr.Data(s) 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). -- 2.50.0