]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: make symbol data writable before toc fixup
authorPaul E. Murphy <murp@ibm.com>
Tue, 23 Mar 2021 20:40:54 +0000 (15:40 -0500)
committerLynn Boger <laboger@linux.vnet.ibm.com>
Thu, 25 Mar 2021 17:01:28 +0000 (17:01 +0000)
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>

src/cmd/link/internal/ppc64/asm.go

index aa2532ad37c6c7e9b39566da73189d391cbc9ff6..e8e258a1f3af81886cb6cf32e84882754e324f24 100644 (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()
+
+                       // 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).