mirror of
https://github.com/golang/go
synced 2024-11-18 08:54:45 -07:00
cmd/internal/obj, cmd/link: support inital-exec TLS on arm64
Change-Id: Iaf9159a68fa395245bc20ccb4a2a377f89371a7e Reviewed-on: https://go-review.googlesource.com/13996 Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
parent
72180c3b82
commit
80d9106487
@ -321,7 +321,16 @@ const (
|
|||||||
C_LOREG
|
C_LOREG
|
||||||
|
|
||||||
C_ADDR // TODO(aram): explain difference from C_VCONADDR
|
C_ADDR // TODO(aram): explain difference from C_VCONADDR
|
||||||
C_TLS // TLS var, i.e. memory address containing offset for the var
|
|
||||||
|
// TLS "var" in local exec mode: will become a constant offset from
|
||||||
|
// thread local base that is ultimately chosen by the program linker.
|
||||||
|
C_TLS_LE
|
||||||
|
|
||||||
|
// TLS "var" in initial exec mode: will become a memory address (chosen
|
||||||
|
// by the program linker) that the dynamic linker will fill with the
|
||||||
|
// offset from the thread local base.
|
||||||
|
C_TLS_IE
|
||||||
|
|
||||||
C_ROFF // register offset (including register extended)
|
C_ROFF // register offset (including register extended)
|
||||||
|
|
||||||
C_GOK
|
C_GOK
|
||||||
|
@ -55,7 +55,8 @@ var cnames7 = []string{
|
|||||||
"UOREG64K",
|
"UOREG64K",
|
||||||
"LOREG",
|
"LOREG",
|
||||||
"ADDR",
|
"ADDR",
|
||||||
"TLS",
|
"TLS_LE",
|
||||||
|
"TLS_IE",
|
||||||
"ROFF",
|
"ROFF",
|
||||||
"GOK",
|
"GOK",
|
||||||
"TEXTSIZE",
|
"TEXTSIZE",
|
||||||
|
@ -270,7 +270,8 @@ var optab = []Optab{
|
|||||||
{AMOVH, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0},
|
{AMOVH, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0},
|
||||||
{AMOVW, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0},
|
{AMOVW, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0},
|
||||||
{AMOVD, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0},
|
{AMOVD, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0},
|
||||||
{AMOVD, C_TLS, C_NONE, C_REG, 69, 4, 0, 0, 0},
|
{AMOVD, C_TLS_LE, C_NONE, C_REG, 69, 4, 0, 0, 0},
|
||||||
|
{AMOVD, C_TLS_IE, C_NONE, C_REG, 70, 8, 0, 0, 0},
|
||||||
{AMUL, C_REG, C_REG, C_REG, 15, 4, 0, 0, 0},
|
{AMUL, C_REG, C_REG, C_REG, 15, 4, 0, 0, 0},
|
||||||
{AMUL, C_REG, C_NONE, C_REG, 15, 4, 0, 0, 0},
|
{AMUL, C_REG, C_NONE, C_REG, 15, 4, 0, 0, 0},
|
||||||
{AMADD, C_REG, C_REG, C_REG, 15, 4, 0, 0, 0},
|
{AMADD, C_REG, C_REG, C_REG, 15, 4, 0, 0, 0},
|
||||||
@ -970,7 +971,11 @@ 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 {
|
if a.Sym.Type == obj.STLSBSS {
|
||||||
return C_TLS
|
if ctxt.Flag_shared != 0 {
|
||||||
|
return C_TLS_IE
|
||||||
|
} else {
|
||||||
|
return C_TLS_LE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return C_ADDR
|
return C_ADDR
|
||||||
}
|
}
|
||||||
@ -1045,10 +1050,12 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
|||||||
|
|
||||||
case obj.NAME_EXTERN,
|
case obj.NAME_EXTERN,
|
||||||
obj.NAME_STATIC:
|
obj.NAME_STATIC:
|
||||||
s := a.Sym
|
if a.Sym == nil {
|
||||||
if s == nil {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if a.Sym.Type == obj.STLSBSS {
|
||||||
|
ctxt.Diag("taking address of TLS variable is not supported")
|
||||||
|
}
|
||||||
ctxt.Instoffset = a.Offset
|
ctxt.Instoffset = a.Offset
|
||||||
return C_VCONADDR
|
return C_VCONADDR
|
||||||
|
|
||||||
@ -2757,7 +2764,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
rel.Add = p.From.Offset
|
rel.Add = p.From.Offset
|
||||||
rel.Type = obj.R_ADDRARM64
|
rel.Type = obj.R_ADDRARM64
|
||||||
|
|
||||||
case 69: /* movd $tlsvar, reg -> movz reg, 0 + reloc */
|
case 69: /* LE model movd $tlsvar, reg -> movz reg, 0 + reloc */
|
||||||
o1 = opirr(ctxt, AMOVZ)
|
o1 = opirr(ctxt, AMOVZ)
|
||||||
o1 |= uint32(p.To.Reg & 31)
|
o1 |= uint32(p.To.Reg & 31)
|
||||||
rel := obj.Addrel(ctxt.Cursym)
|
rel := obj.Addrel(ctxt.Cursym)
|
||||||
@ -2769,6 +2776,19 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
ctxt.Diag("invalid offset on MOVW $tlsvar")
|
ctxt.Diag("invalid offset on MOVW $tlsvar")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 70: /* IE model movd $tlsvar, reg -> adrp REGTMP, 0; ldr reg, [REGTMP, #0] + relocs */
|
||||||
|
o1 = ADR(1, 0, REGTMP)
|
||||||
|
o2 = olsr12u(ctxt, int32(opldr12(ctxt, AMOVD)), 0, REGTMP, int(p.To.Reg))
|
||||||
|
rel := obj.Addrel(ctxt.Cursym)
|
||||||
|
rel.Off = int32(ctxt.Pc)
|
||||||
|
rel.Siz = 8
|
||||||
|
rel.Sym = p.From.Sym
|
||||||
|
rel.Add = 0
|
||||||
|
rel.Type = obj.R_ARM64_TLS_IE
|
||||||
|
if p.From.Offset != 0 {
|
||||||
|
ctxt.Diag("invalid offset on MOVW $tlsvar")
|
||||||
|
}
|
||||||
|
|
||||||
// This is supposed to be something that stops execution.
|
// This is supposed to be something that stops execution.
|
||||||
// It's not supposed to be reached, ever, but if it is, we'd
|
// It's not supposed to be reached, ever, but if it is, we'd
|
||||||
// like to be able to tell how we got there. Assemble as
|
// like to be able to tell how we got there. Assemble as
|
||||||
|
@ -446,6 +446,11 @@ const (
|
|||||||
// local base to the thread local variable defined by the referenced (thread
|
// local base to the thread local variable defined by the referenced (thread
|
||||||
// local) symbol. Error if the offset does not fit into 16 bits.
|
// local) symbol. Error if the offset does not fit into 16 bits.
|
||||||
R_ARM64_TLS_LE
|
R_ARM64_TLS_LE
|
||||||
|
|
||||||
|
// Relocates an ADRP; LD64 instruction sequence to load the offset between
|
||||||
|
// the thread local base and the thread local variable defined by the
|
||||||
|
// referenced (thread local) symbol from the GOT.
|
||||||
|
R_ARM64_TLS_IE
|
||||||
)
|
)
|
||||||
|
|
||||||
type Auto struct {
|
type Auto struct {
|
||||||
|
@ -76,6 +76,12 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
|||||||
case obj.R_ARM64_TLS_LE:
|
case obj.R_ARM64_TLS_LE:
|
||||||
ld.Thearch.Vput(ld.R_AARCH64_TLSLE_MOVW_TPREL_G0 | uint64(elfsym)<<32)
|
ld.Thearch.Vput(ld.R_AARCH64_TLSLE_MOVW_TPREL_G0 | uint64(elfsym)<<32)
|
||||||
|
|
||||||
|
case obj.R_ARM64_TLS_IE:
|
||||||
|
ld.Thearch.Vput(ld.R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 | uint64(elfsym)<<32)
|
||||||
|
ld.Thearch.Vput(uint64(r.Xadd))
|
||||||
|
ld.Thearch.Vput(uint64(sectoff + 4))
|
||||||
|
ld.Thearch.Vput(ld.R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC | uint64(elfsym)<<32)
|
||||||
|
|
||||||
case obj.R_CALLARM64:
|
case obj.R_CALLARM64:
|
||||||
if r.Siz != 4 {
|
if r.Siz != 4 {
|
||||||
return -1
|
return -1
|
||||||
@ -229,7 +235,8 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
case obj.R_CALLARM64,
|
case obj.R_CALLARM64,
|
||||||
obj.R_ARM64_TLS_LE:
|
obj.R_ARM64_TLS_LE,
|
||||||
|
obj.R_ARM64_TLS_IE:
|
||||||
r.Done = 0
|
r.Done = 0
|
||||||
r.Xsym = r.Sym
|
r.Xsym = r.Sym
|
||||||
r.Xadd = r.Add
|
r.Xadd = r.Add
|
||||||
|
@ -351,12 +351,14 @@ const (
|
|||||||
R_X86_64_TPOFF32 = 23
|
R_X86_64_TPOFF32 = 23
|
||||||
R_X86_64_COUNT = 24
|
R_X86_64_COUNT = 24
|
||||||
|
|
||||||
R_AARCH64_ABS64 = 257
|
R_AARCH64_ABS64 = 257
|
||||||
R_AARCH64_ABS32 = 258
|
R_AARCH64_ABS32 = 258
|
||||||
R_AARCH64_CALL26 = 283
|
R_AARCH64_CALL26 = 283
|
||||||
R_AARCH64_ADR_PREL_PG_HI21 = 275
|
R_AARCH64_ADR_PREL_PG_HI21 = 275
|
||||||
R_AARCH64_ADD_ABS_LO12_NC = 277
|
R_AARCH64_ADD_ABS_LO12_NC = 277
|
||||||
R_AARCH64_TLSLE_MOVW_TPREL_G0 = 547
|
R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 = 541
|
||||||
|
R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC = 542
|
||||||
|
R_AARCH64_TLSLE_MOVW_TPREL_G0 = 547
|
||||||
|
|
||||||
R_ALPHA_NONE = 0
|
R_ALPHA_NONE = 0
|
||||||
R_ALPHA_REFLONG = 1
|
R_ALPHA_REFLONG = 1
|
||||||
|
Loading…
Reference in New Issue
Block a user