]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj, cmd/link: generate position independent loads of static data
authorMichael Hudson-Doyle <michael.hudson@canonical.com>
Fri, 16 Oct 2015 07:48:56 +0000 (20:48 +1300)
committerMichael Hudson-Doyle <michael.hudson@canonical.com>
Thu, 12 Nov 2015 23:33:12 +0000 (23:33 +0000)
Change-Id: I0a8448c2b69f5cfa6f099d772f5eb3412f853045
Reviewed-on: https://go-review.googlesource.com/15969
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/internal/obj/link.go
src/cmd/internal/obj/ppc64/asm9.go
src/cmd/link/internal/ppc64/asm.go

index 71784d8b01400912135052e41b1e34ab732947ba..ab1de2447b76e85367d9df5f60d3b74993bf54f8 100644 (file)
@@ -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 {
index 22514e514e88dcd850dee5553eb5aa19a6ba571a..c226ed540db125312af6b844ba0f8b8be5717c4a 100644 (file)
@@ -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
 }
index 54b9c38cc5b7b8a76bfb42260a534757b197a28c..97efe7d354f06f0e6cecd425ba26e01e984ce11c 100644 (file)
@@ -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