mirror of
https://github.com/golang/go
synced 2024-11-24 06:50:17 -07:00
cmd/internal/obj/mips, cmd/link: add support TLS relocation for mips64x
a new relocation R_ADDRMIPSTLS is added, which resolves to 16-bit offset of a TLS address on mips64x. Change-Id: Ic60d0e1ba49ff1c433cead242f5884677ab227a5 Reviewed-on: https://go-review.googlesource.com/19804 Reviewed-by: Minux Ma <minux@golang.org>
This commit is contained in:
parent
77c7f12438
commit
3b0b30727c
@ -585,6 +585,9 @@ const (
|
||||
// R_ADDRMIPSU (only used on mips64) resolves to the sign-adjusted "upper" 16
|
||||
// bits (bit 16-31) of an external address, by encoding it into the instruction.
|
||||
R_ADDRMIPSU
|
||||
// R_ADDRMIPSTLS (only used on mips64) resolves to the low 16 bits of a TLS
|
||||
// address (offset from thread pointer), by encoding it into the instruction.
|
||||
R_ADDRMIPSTLS
|
||||
)
|
||||
|
||||
type Auto struct {
|
||||
|
@ -243,6 +243,7 @@ const (
|
||||
C_LACON /* $n(REG) where int16 < n <= int32 */
|
||||
C_LECON
|
||||
C_DACON /* $n(REG) where int32 < n */
|
||||
C_STCON /* $tlsvar */
|
||||
C_SBRA
|
||||
C_LBRA
|
||||
C_SAUTO
|
||||
@ -254,6 +255,7 @@ const (
|
||||
C_LOREG
|
||||
C_GOK
|
||||
C_ADDR
|
||||
C_TLS
|
||||
C_TEXTSIZE
|
||||
|
||||
C_NCLASS /* must be the last */
|
||||
|
@ -26,6 +26,7 @@ var cnames0 = []string{
|
||||
"LACON",
|
||||
"LECON",
|
||||
"DACON",
|
||||
"STCON",
|
||||
"SBRA",
|
||||
"LBRA",
|
||||
"SAUTO",
|
||||
@ -37,6 +38,7 @@ var cnames0 = []string{
|
||||
"LOREG",
|
||||
"GOK",
|
||||
"ADDR",
|
||||
"TLS",
|
||||
"TEXTSIZE",
|
||||
"NCLASS",
|
||||
}
|
||||
|
@ -141,6 +141,11 @@ var optab = []Optab{
|
||||
{AMOVV, C_REG, C_NONE, C_ADDR, 50, 12, 0},
|
||||
{AMOVB, C_REG, C_NONE, C_ADDR, 50, 12, 0},
|
||||
{AMOVBU, C_REG, C_NONE, C_ADDR, 50, 12, 0},
|
||||
{AMOVW, C_REG, C_NONE, C_TLS, 53, 8, 0},
|
||||
{AMOVWU, C_REG, C_NONE, C_TLS, 53, 8, 0},
|
||||
{AMOVV, C_REG, C_NONE, C_TLS, 53, 8, 0},
|
||||
{AMOVB, C_REG, C_NONE, C_TLS, 53, 8, 0},
|
||||
{AMOVBU, C_REG, C_NONE, C_TLS, 53, 8, 0},
|
||||
|
||||
{AMOVW, C_LEXT, C_NONE, C_REG, 36, 12, REGSB},
|
||||
{AMOVWU, C_LEXT, C_NONE, C_REG, 36, 12, REGSB},
|
||||
@ -162,6 +167,11 @@ var optab = []Optab{
|
||||
{AMOVV, C_ADDR, C_NONE, C_REG, 51, 12, 0},
|
||||
{AMOVB, C_ADDR, C_NONE, C_REG, 51, 12, 0},
|
||||
{AMOVBU, C_ADDR, C_NONE, C_REG, 51, 12, 0},
|
||||
{AMOVW, C_TLS, C_NONE, C_REG, 54, 8, 0},
|
||||
{AMOVWU, C_TLS, C_NONE, C_REG, 54, 8, 0},
|
||||
{AMOVV, C_TLS, C_NONE, C_REG, 54, 8, 0},
|
||||
{AMOVB, C_TLS, C_NONE, C_REG, 54, 8, 0},
|
||||
{AMOVBU, C_TLS, C_NONE, C_REG, 54, 8, 0},
|
||||
|
||||
{AMOVW, C_SECON, C_NONE, C_REG, 3, 4, REGSB},
|
||||
{AMOVV, C_SECON, C_NONE, C_REG, 3, 4, REGSB},
|
||||
@ -175,6 +185,8 @@ var optab = []Optab{
|
||||
{AMOVV, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO},
|
||||
{AMOVW, C_ANDCON, C_NONE, C_REG, 3, 4, REGZERO},
|
||||
{AMOVV, C_ANDCON, C_NONE, C_REG, 3, 4, REGZERO},
|
||||
{AMOVW, C_STCON, C_NONE, C_REG, 55, 8, 0},
|
||||
{AMOVV, C_STCON, C_NONE, C_REG, 55, 8, 0},
|
||||
|
||||
{AMOVW, C_UCON, C_NONE, C_REG, 24, 4, 0},
|
||||
{AMOVV, C_UCON, C_NONE, C_REG, 24, 4, 0},
|
||||
@ -476,6 +488,9 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
||||
}
|
||||
ctxt.Instoffset = a.Offset
|
||||
if a.Sym != nil { // use relocation
|
||||
if a.Sym.Type == obj.STLSBSS {
|
||||
return C_TLS
|
||||
}
|
||||
return C_ADDR
|
||||
}
|
||||
return C_LEXT
|
||||
@ -539,6 +554,9 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
||||
}
|
||||
|
||||
ctxt.Instoffset = a.Offset
|
||||
if s.Type == obj.STLSBSS {
|
||||
return C_STCON // address of TLS variable
|
||||
}
|
||||
return C_LECON
|
||||
|
||||
case obj.NAME_AUTO:
|
||||
@ -1387,6 +1405,40 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||
rel2.Sym = p.From.Sym
|
||||
rel2.Add = p.From.Offset
|
||||
rel2.Type = obj.R_ADDRMIPS
|
||||
|
||||
case 53: /* mov r, tlsvar ==> rdhwr + sw o(r3) */
|
||||
// clobbers R3 !
|
||||
// load thread pointer with RDHWR, R3 is used for fast kernel emulation on Linux
|
||||
o1 = (037<<26 + 073) | (29 << 11) | (3 << 16) // rdhwr $29, r3
|
||||
o2 = OP_IRR(opirr(ctxt, p.As), uint32(0), uint32(REG_R3), uint32(p.From.Reg))
|
||||
rel := obj.Addrel(ctxt.Cursym)
|
||||
rel.Off = int32(ctxt.Pc + 4)
|
||||
rel.Siz = 4
|
||||
rel.Sym = p.To.Sym
|
||||
rel.Add = p.To.Offset
|
||||
rel.Type = obj.R_ADDRMIPSTLS
|
||||
|
||||
case 54: /* mov tlsvar, r ==> rdhwr + lw o(r3) */
|
||||
// clobbers R3 !
|
||||
o1 = (037<<26 + 073) | (29 << 11) | (3 << 16) // rdhwr $29, r3
|
||||
o2 = OP_IRR(opirr(ctxt, -p.As), uint32(0), uint32(REG_R3), uint32(p.To.Reg))
|
||||
rel := obj.Addrel(ctxt.Cursym)
|
||||
rel.Off = int32(ctxt.Pc + 4)
|
||||
rel.Siz = 4
|
||||
rel.Sym = p.From.Sym
|
||||
rel.Add = p.From.Offset
|
||||
rel.Type = obj.R_ADDRMIPSTLS
|
||||
|
||||
case 55: /* mov $tlsvar, r ==> rdhwr + add */
|
||||
// clobbers R3 !
|
||||
o1 = (037<<26 + 073) | (29 << 11) | (3 << 16) // rdhwr $29, r3
|
||||
o2 = OP_IRR(opirr(ctxt, AADDVU), uint32(0), uint32(REG_R3), uint32(p.To.Reg))
|
||||
rel := obj.Addrel(ctxt.Cursym)
|
||||
rel.Off = int32(ctxt.Pc + 4)
|
||||
rel.Siz = 4
|
||||
rel.Sym = p.From.Sym
|
||||
rel.Add = p.From.Offset
|
||||
rel.Type = obj.R_ADDRMIPSTLS
|
||||
}
|
||||
|
||||
out[0] = o1
|
||||
|
@ -81,6 +81,9 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
||||
case obj.R_ADDRMIPSU:
|
||||
ld.Cput(ld.R_MIPS_HI16)
|
||||
|
||||
case obj.R_ADDRMIPSTLS:
|
||||
ld.Cput(ld.R_MIPS_TLS_TPREL_LO16)
|
||||
|
||||
case obj.R_CALLMIPS,
|
||||
obj.R_JMPMIPS:
|
||||
ld.Cput(ld.R_MIPS_26)
|
||||
@ -123,7 +126,8 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
|
||||
|
||||
return 0
|
||||
|
||||
case obj.R_CALLMIPS,
|
||||
case obj.R_ADDRMIPSTLS,
|
||||
obj.R_CALLMIPS,
|
||||
obj.R_JMPMIPS:
|
||||
r.Done = 0
|
||||
r.Xsym = r.Sym
|
||||
@ -152,6 +156,16 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
|
||||
}
|
||||
return 0
|
||||
|
||||
case obj.R_ADDRMIPSTLS:
|
||||
// thread pointer is at 0x7000 offset from the start of TLS data area
|
||||
t := ld.Symaddr(r.Sym) + r.Add - 0x7000
|
||||
if t < -32768 || t >= 32678 {
|
||||
ld.Diag("TLS offset out of range %d", t)
|
||||
}
|
||||
o1 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:])
|
||||
*val = int64(o1&0xffff0000 | uint32(t)&0xffff)
|
||||
return 0
|
||||
|
||||
case obj.R_CALLMIPS,
|
||||
obj.R_JMPMIPS:
|
||||
// Low 26 bits = (S + A) >> 2
|
||||
|
Loading…
Reference in New Issue
Block a user