aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Munday <mike.munday@ibm.com>2017-09-20 12:12:33 -0400
committerMichael Munday <mike.munday@ibm.com>2017-09-20 20:20:46 +0000
commit55ac5b50b079b14bcab4dc1a971d84516cd4bf75 (patch)
tree6facc9b7abb7f124f73be0b9b8656d8abdb921bf /src
parent0d73f1e333bc9d0b0c07345efc498ebecaebf786 (diff)
downloadgo-55ac5b50b079b14bcab4dc1a971d84516cd4bf75.tar.xz
cmd/compile: fix large global variables in -linkshared mode on s390x
When rewriting loads and stores accessing global variables to use the GOT we were making use of REGTMP (R10). Unfortunately loads and stores with large offsets (larger than 20-bits) were also using REGTMP, causing it to be clobbered and subsequently a segmentation fault. This can be fixed by using REGTMP2 (R11) for the rewrite. This is fine because REGTMP2 only has a couple of uses in the assembler (division, high multiplication and storage-to-storage instructions). We didn't use REGTMP2 originally because it used to be used more frequently, in particular for stores of constants to memory. However we have now eliminated those uses. This was found while writing a test case for CL 63030. That test case is included in this CL. Change-Id: I13956f1f3ca258a7c8a7ff0a7570d2848adf7f68 Reviewed-on: https://go-review.googlesource.com/65011 Reviewed-by: Cherry Zhang <cherryyz@google.com> Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/internal/obj/s390x/objz.go12
1 files changed, 6 insertions, 6 deletions
diff --git a/src/cmd/internal/obj/s390x/objz.go b/src/cmd/internal/obj/s390x/objz.go
index 1539de67c8..45ce68bebf 100644
--- a/src/cmd/internal/obj/s390x/objz.go
+++ b/src/cmd/internal/obj/s390x/objz.go
@@ -126,7 +126,7 @@ func (c *ctxtz) rewriteToUseGot(p *obj.Prog) {
// ADD instruction.
if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
// MOVD $sym, Rx becomes MOVD sym@GOT, Rx
- // MOVD $sym+<off>, Rx becomes MOVD sym@GOT, Rx; MOVD $<off>(Rx or REGTMP2), Rx
+ // MOVD $sym+<off>, Rx becomes MOVD sym@GOT, Rx or REGTMP2; MOVD $<off>(Rx or REGTMP2), Rx
if p.To.Type != obj.TYPE_REG || p.As != AMOVD {
c.ctxt.Diag("do not know how to handle LEA-type insn to non-register in %v with -dynlink", p)
}
@@ -154,8 +154,8 @@ func (c *ctxtz) rewriteToUseGot(p *obj.Prog) {
c.ctxt.Diag("don't know how to handle %v with -dynlink", p)
}
var source *obj.Addr
- // MOVD sym, Ry becomes MOVD sym@GOT, REGTMP; MOVD (REGTMP), Ry
- // MOVD Ry, sym becomes MOVD sym@GOT, REGTMP; MOVD Ry, (REGTMP)
+ // MOVD sym, Ry becomes MOVD sym@GOT, REGTMP2; MOVD (REGTMP2), Ry
+ // MOVD Ry, sym becomes MOVD sym@GOT, REGTMP2; MOVD Ry, (REGTMP2)
// An addition may be inserted between the two MOVs if there is an offset.
if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
@@ -184,17 +184,17 @@ func (c *ctxtz) rewriteToUseGot(p *obj.Prog) {
p1.From.Sym = source.Sym
p1.From.Name = obj.NAME_GOTREF
p1.To.Type = obj.TYPE_REG
- p1.To.Reg = REGTMP
+ p1.To.Reg = REGTMP2
p2.As = p.As
p2.From = p.From
p2.To = p.To
if p.From.Name == obj.NAME_EXTERN {
- p2.From.Reg = REGTMP
+ p2.From.Reg = REGTMP2
p2.From.Name = obj.NAME_NONE
p2.From.Sym = nil
} else if p.To.Name == obj.NAME_EXTERN {
- p2.To.Reg = REGTMP
+ p2.To.Reg = REGTMP2
p2.To.Name = obj.NAME_NONE
p2.To.Sym = nil
} else {