Commit bd329d47 authored by Michael Hudson-Doyle's avatar Michael Hudson-Doyle

cmd/internal/obj, cmd/link: generate position independent loads of static data

Change-Id: I0a8448c2b69f5cfa6f099d772f5eb3412f853045
Reviewed-on: https://go-review.googlesource.com/15969Reviewed-by: 's avatarRuss Cox <rsc@golang.org>
parent 368d5484
......@@ -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 {
......
......@@ -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
}
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment