From: Paul E. Murphy Date: Tue, 23 Mar 2021 20:40:54 +0000 (-0500) Subject: cmd/link: make symbol data writable before toc fixup X-Git-Tag: go1.17beta1~976 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=82a1e0f9d3;p=gostls13.git 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 --- 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).