From bd329d47d9f4ebf6f627372ed28315030d05f7b7 Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Fri, 16 Oct 2015 20:48:56 +1300 Subject: [PATCH] cmd/internal/obj, cmd/link: generate position independent loads of static data Change-Id: I0a8448c2b69f5cfa6f099d772f5eb3412f853045 Reviewed-on: https://go-review.googlesource.com/15969 Reviewed-by: Russ Cox --- src/cmd/internal/obj/link.go | 10 ++++++++++ src/cmd/internal/obj/ppc64/asm9.go | 28 ++++++++++++++++++++++------ src/cmd/link/internal/ppc64/asm.go | 14 ++++++++++++++ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go index 71784d8b01..ab1de2447b 100644 --- a/src/cmd/internal/obj/link.go +++ b/src/cmd/internal/obj/link.go @@ -491,6 +491,16 @@ const ( // inserts the displacement from the place being relocated to the address of the // the relocated symbol instead of just its address. R_ADDRPOWER_PCREL + + // R_ADDRPOWER_TOCREL relocates two D-form instructions like R_ADDRPOWER, but + // inserts the offset from the TOC to the address of the the relocated symbol + // rather than the symbol's address. + R_ADDRPOWER_TOCREL + + // R_ADDRPOWER_TOCREL relocates a D-form, DS-form instruction sequence like + // R_ADDRPOWER_DS but inserts the offset from the TOC to the address of the the + // relocated symbol rather than the symbol's address. + R_ADDRPOWER_TOCREL_DS ) type Auto struct { diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go index 22514e514e..c226ed540d 100644 --- a/src/cmd/internal/obj/ppc64/asm9.go +++ b/src/cmd/internal/obj/ppc64/asm9.go @@ -1417,19 +1417,35 @@ func opform(ctxt *obj.Link, insn int32) int { // Encode instructions and create relocation for accessing s+d according to the // instruction op with source or destination (as appropriate) register reg. func symbolAccess(ctxt *obj.Link, s *obj.LSym, d int64, reg int16, op int32) (o1, o2 uint32) { + var base uint32 form := opform(ctxt, op) - o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, 0) + if ctxt.Flag_shared != 0 { + base = REG_R2 + } else { + base = REG_R0 + } + o1 = AOP_IRR(OP_ADDIS, REGTMP, base, 0) o2 = AOP_IRR(uint32(op), uint32(reg), REGTMP, 0) rel := obj.Addrel(ctxt.Cursym) rel.Off = int32(ctxt.Pc) rel.Siz = 8 rel.Sym = s rel.Add = d - switch form { - case D_FORM: - rel.Type = obj.R_ADDRPOWER - case DS_FORM: - rel.Type = obj.R_ADDRPOWER_DS + if ctxt.Flag_shared != 0 { + switch form { + case D_FORM: + rel.Type = obj.R_ADDRPOWER_TOCREL + case DS_FORM: + rel.Type = obj.R_ADDRPOWER_TOCREL_DS + } + + } else { + switch form { + case D_FORM: + rel.Type = obj.R_ADDRPOWER + case DS_FORM: + rel.Type = obj.R_ADDRPOWER_DS + } } return } diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go index 54b9c38cc5..97efe7d354 100644 --- a/src/cmd/link/internal/ppc64/asm.go +++ b/src/cmd/link/internal/ppc64/asm.go @@ -332,6 +332,18 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int { ld.Thearch.Vput(ld.R_PPC64_REL16_LO | uint64(elfsym)<<32) r.Xadd += 4 + case obj.R_ADDRPOWER_TOCREL: + ld.Thearch.Vput(ld.R_PPC64_TOC16_HA | uint64(elfsym)<<32) + ld.Thearch.Vput(uint64(r.Xadd)) + ld.Thearch.Vput(uint64(sectoff + 4)) + ld.Thearch.Vput(ld.R_PPC64_TOC16_LO | uint64(elfsym)<<32) + + case obj.R_ADDRPOWER_TOCREL_DS: + ld.Thearch.Vput(ld.R_PPC64_TOC16_HA | uint64(elfsym)<<32) + ld.Thearch.Vput(uint64(r.Xadd)) + ld.Thearch.Vput(uint64(sectoff + 4)) + ld.Thearch.Vput(ld.R_PPC64_TOC16_LO_DS | uint64(elfsym)<<32) + case obj.R_CALLPOWER: if r.Siz != 4 { return -1 @@ -441,6 +453,8 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int { case obj.R_ADDRPOWER, obj.R_ADDRPOWER_DS, + obj.R_ADDRPOWER_TOCREL, + obj.R_ADDRPOWER_TOCREL_DS, obj.R_ADDRPOWER_PCREL: r.Done = 0 -- 2.48.1