mirror of
https://github.com/golang/go
synced 2024-11-23 14:40:02 -07:00
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 <rsc@golang.org>
This commit is contained in:
parent
368d548417
commit
bd329d47d9
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user