Commit 3b0b3072 authored by Cherry Zhang's avatar Cherry Zhang Committed by Minux Ma

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/19804Reviewed-by: default avatarMinux Ma <minux@golang.org>
parent 77c7f124
...@@ -585,6 +585,9 @@ const ( ...@@ -585,6 +585,9 @@ const (
// R_ADDRMIPSU (only used on mips64) resolves to the sign-adjusted "upper" 16 // 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. // bits (bit 16-31) of an external address, by encoding it into the instruction.
R_ADDRMIPSU 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 { type Auto struct {
......
...@@ -243,6 +243,7 @@ const ( ...@@ -243,6 +243,7 @@ const (
C_LACON /* $n(REG) where int16 < n <= int32 */ C_LACON /* $n(REG) where int16 < n <= int32 */
C_LECON C_LECON
C_DACON /* $n(REG) where int32 < n */ C_DACON /* $n(REG) where int32 < n */
C_STCON /* $tlsvar */
C_SBRA C_SBRA
C_LBRA C_LBRA
C_SAUTO C_SAUTO
...@@ -254,6 +255,7 @@ const ( ...@@ -254,6 +255,7 @@ const (
C_LOREG C_LOREG
C_GOK C_GOK
C_ADDR C_ADDR
C_TLS
C_TEXTSIZE C_TEXTSIZE
C_NCLASS /* must be the last */ C_NCLASS /* must be the last */
......
...@@ -26,6 +26,7 @@ var cnames0 = []string{ ...@@ -26,6 +26,7 @@ var cnames0 = []string{
"LACON", "LACON",
"LECON", "LECON",
"DACON", "DACON",
"STCON",
"SBRA", "SBRA",
"LBRA", "LBRA",
"SAUTO", "SAUTO",
...@@ -37,6 +38,7 @@ var cnames0 = []string{ ...@@ -37,6 +38,7 @@ var cnames0 = []string{
"LOREG", "LOREG",
"GOK", "GOK",
"ADDR", "ADDR",
"TLS",
"TEXTSIZE", "TEXTSIZE",
"NCLASS", "NCLASS",
} }
...@@ -141,6 +141,11 @@ var optab = []Optab{ ...@@ -141,6 +141,11 @@ var optab = []Optab{
{AMOVV, C_REG, C_NONE, C_ADDR, 50, 12, 0}, {AMOVV, C_REG, C_NONE, C_ADDR, 50, 12, 0},
{AMOVB, 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}, {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}, {AMOVW, C_LEXT, C_NONE, C_REG, 36, 12, REGSB},
{AMOVWU, 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{ ...@@ -162,6 +167,11 @@ var optab = []Optab{
{AMOVV, C_ADDR, C_NONE, C_REG, 51, 12, 0}, {AMOVV, C_ADDR, C_NONE, C_REG, 51, 12, 0},
{AMOVB, 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}, {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}, {AMOVW, C_SECON, C_NONE, C_REG, 3, 4, REGSB},
{AMOVV, 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{ ...@@ -175,6 +185,8 @@ var optab = []Optab{
{AMOVV, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO}, {AMOVV, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO},
{AMOVW, C_ANDCON, 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}, {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}, {AMOVW, C_UCON, C_NONE, C_REG, 24, 4, 0},
{AMOVV, 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 { ...@@ -476,6 +488,9 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
} }
ctxt.Instoffset = a.Offset ctxt.Instoffset = a.Offset
if a.Sym != nil { // use relocation if a.Sym != nil { // use relocation
if a.Sym.Type == obj.STLSBSS {
return C_TLS
}
return C_ADDR return C_ADDR
} }
return C_LEXT return C_LEXT
...@@ -539,6 +554,9 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { ...@@ -539,6 +554,9 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
} }
ctxt.Instoffset = a.Offset ctxt.Instoffset = a.Offset
if s.Type == obj.STLSBSS {
return C_STCON // address of TLS variable
}
return C_LECON return C_LECON
case obj.NAME_AUTO: case obj.NAME_AUTO:
...@@ -1387,6 +1405,40 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { ...@@ -1387,6 +1405,40 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
rel2.Sym = p.From.Sym rel2.Sym = p.From.Sym
rel2.Add = p.From.Offset rel2.Add = p.From.Offset
rel2.Type = obj.R_ADDRMIPS 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 out[0] = o1
......
...@@ -81,6 +81,9 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -81,6 +81,9 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
case obj.R_ADDRMIPSU: case obj.R_ADDRMIPSU:
ld.Cput(ld.R_MIPS_HI16) ld.Cput(ld.R_MIPS_HI16)
case obj.R_ADDRMIPSTLS:
ld.Cput(ld.R_MIPS_TLS_TPREL_LO16)
case obj.R_CALLMIPS, case obj.R_CALLMIPS,
obj.R_JMPMIPS: obj.R_JMPMIPS:
ld.Cput(ld.R_MIPS_26) ld.Cput(ld.R_MIPS_26)
...@@ -123,7 +126,8 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int { ...@@ -123,7 +126,8 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
return 0 return 0
case obj.R_CALLMIPS, case obj.R_ADDRMIPSTLS,
obj.R_CALLMIPS,
obj.R_JMPMIPS: obj.R_JMPMIPS:
r.Done = 0 r.Done = 0
r.Xsym = r.Sym r.Xsym = r.Sym
...@@ -152,6 +156,16 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int { ...@@ -152,6 +156,16 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
} }
return 0 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, case obj.R_CALLMIPS,
obj.R_JMPMIPS: obj.R_JMPMIPS:
// Low 26 bits = (S + A) >> 2 // Low 26 bits = (S + A) >> 2
......
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