207 lines
9.0 KiB
Diff
207 lines
9.0 KiB
Diff
From 98d9c96b21ae096926575363091ec1fccfd6416e Mon Sep 17 00:00:00 2001
|
|
From: Joel Sing <joel@sing.id.au>
|
|
Date: Tue, 19 May 2020 18:55:10 +1000
|
|
Subject: [PATCH] cmd/link,cmd/internal/obj/riscv: add TLS support for
|
|
linux/riscv64
|
|
|
|
Add support for Thread Local Storage (TLS) for linux/riscv64 with external
|
|
linking, using the initial-exec model.
|
|
|
|
Change-Id: I3106ef9a29cde73215830b00deff43dbec1c76e0
|
|
---
|
|
src/cmd/internal/obj/riscv/obj.go | 7 +++
|
|
src/cmd/internal/objabi/reloctype.go | 8 ++++
|
|
src/cmd/internal/objabi/reloctype_string.go | 67 ++++++++++++++++++++++++++++-
|
|
src/cmd/link/internal/riscv64/asm.go | 15 +++++--
|
|
src/cmd/link/link_test.go | 4 ++
|
|
5 files changed, 96 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go
|
|
index 2eb2935..69c9a31 100644
|
|
--- a/src/cmd/internal/obj/riscv/obj.go
|
|
+++ b/src/cmd/internal/obj/riscv/obj.go
|
|
@@ -1982,6 +1982,13 @@ func assemble(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|
ctxt.Diag("AUIPC needing PC-relative reloc missing symbol")
|
|
break
|
|
}
|
|
+ if addr.Sym.Type == objabi.STLSBSS {
|
|
+ if rt == objabi.R_RISCV_PCREL_ITYPE {
|
|
+ rt = objabi.R_RISCV_TLS_IE_ITYPE
|
|
+ } else if rt == objabi.R_RISCV_PCREL_STYPE {
|
|
+ rt = objabi.R_RISCV_TLS_IE_STYPE
|
|
+ }
|
|
+ }
|
|
|
|
rel := obj.Addrel(cursym)
|
|
rel.Off = int32(p.Pc)
|
|
diff --git a/src/cmd/internal/objabi/reloctype.go b/src/cmd/internal/objabi/reloctype.go
|
|
index f029a3c..b84abce 100644
|
|
--- a/src/cmd/internal/objabi/reloctype.go
|
|
+++ b/src/cmd/internal/objabi/reloctype.go
|
|
@@ -212,6 +212,14 @@ const (
|
|
// AUIPC + S-type instruction pair.
|
|
R_RISCV_PCREL_STYPE
|
|
|
|
+ // R_RISCV_TLS_IE_ITYPE resolves a 32-bit TLS initial-exec TOC offset
|
|
+ // address using an AUIPC + I-type instruction pair.
|
|
+ R_RISCV_TLS_IE_ITYPE
|
|
+
|
|
+ // R_RISCV_TLS_IE_STYPE resolves a 32-bit TLS initial-exec TOC offset
|
|
+ // address using an AUIPC + S-type instruction pair.
|
|
+ R_RISCV_TLS_IE_STYPE
|
|
+
|
|
// R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses.
|
|
// TODO(mundaym): remove once variants can be serialized - see issue 14218.
|
|
R_PCRELDBL
|
|
diff --git a/src/cmd/internal/objabi/reloctype_string.go b/src/cmd/internal/objabi/reloctype_string.go
|
|
index 83dfe71..b9843fd 100644
|
|
--- a/src/cmd/internal/objabi/reloctype_string.go
|
|
+++ b/src/cmd/internal/objabi/reloctype_string.go
|
|
@@ -4,9 +4,72 @@ package objabi
|
|
|
|
import "strconv"
|
|
|
|
-const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF"
|
|
+func _() {
|
|
+ // An "invalid array index" compiler error signifies that the constant values have changed.
|
|
+ // Re-run the stringer command to generate them again.
|
|
+ var x [1]struct{}
|
|
+ _ = x[R_ADDR-1]
|
|
+ _ = x[R_ADDRPOWER-2]
|
|
+ _ = x[R_ADDRARM64-3]
|
|
+ _ = x[R_ADDRMIPS-4]
|
|
+ _ = x[R_ADDROFF-5]
|
|
+ _ = x[R_WEAKADDROFF-6]
|
|
+ _ = x[R_SIZE-7]
|
|
+ _ = x[R_CALL-8]
|
|
+ _ = x[R_CALLARM-9]
|
|
+ _ = x[R_CALLARM64-10]
|
|
+ _ = x[R_CALLIND-11]
|
|
+ _ = x[R_CALLPOWER-12]
|
|
+ _ = x[R_CALLMIPS-13]
|
|
+ _ = x[R_CALLRISCV-14]
|
|
+ _ = x[R_CONST-15]
|
|
+ _ = x[R_PCREL-16]
|
|
+ _ = x[R_TLS_LE-17]
|
|
+ _ = x[R_TLS_IE-18]
|
|
+ _ = x[R_GOTOFF-19]
|
|
+ _ = x[R_PLT0-20]
|
|
+ _ = x[R_PLT1-21]
|
|
+ _ = x[R_PLT2-22]
|
|
+ _ = x[R_USEFIELD-23]
|
|
+ _ = x[R_USETYPE-24]
|
|
+ _ = x[R_METHODOFF-25]
|
|
+ _ = x[R_POWER_TOC-26]
|
|
+ _ = x[R_GOTPCREL-27]
|
|
+ _ = x[R_JMPMIPS-28]
|
|
+ _ = x[R_DWARFSECREF-29]
|
|
+ _ = x[R_DWARFFILEREF-30]
|
|
+ _ = x[R_ARM64_TLS_LE-31]
|
|
+ _ = x[R_ARM64_TLS_IE-32]
|
|
+ _ = x[R_ARM64_GOTPCREL-33]
|
|
+ _ = x[R_ARM64_GOT-34]
|
|
+ _ = x[R_ARM64_PCREL-35]
|
|
+ _ = x[R_ARM64_LDST8-36]
|
|
+ _ = x[R_ARM64_LDST32-37]
|
|
+ _ = x[R_ARM64_LDST64-38]
|
|
+ _ = x[R_ARM64_LDST128-39]
|
|
+ _ = x[R_POWER_TLS_LE-40]
|
|
+ _ = x[R_POWER_TLS_IE-41]
|
|
+ _ = x[R_POWER_TLS-42]
|
|
+ _ = x[R_ADDRPOWER_DS-43]
|
|
+ _ = x[R_ADDRPOWER_GOT-44]
|
|
+ _ = x[R_ADDRPOWER_PCREL-45]
|
|
+ _ = x[R_ADDRPOWER_TOCREL-46]
|
|
+ _ = x[R_ADDRPOWER_TOCREL_DS-47]
|
|
+ _ = x[R_RISCV_PCREL_ITYPE-48]
|
|
+ _ = x[R_RISCV_PCREL_STYPE-49]
|
|
+ _ = x[R_RISCV_TLS_IE_ITYPE-50]
|
|
+ _ = x[R_RISCV_TLS_IE_STYPE-51]
|
|
+ _ = x[R_PCRELDBL-52]
|
|
+ _ = x[R_ADDRMIPSU-53]
|
|
+ _ = x[R_ADDRMIPSTLS-54]
|
|
+ _ = x[R_ADDRCUOFF-55]
|
|
+ _ = x[R_WASMIMPORT-56]
|
|
+ _ = x[R_XCOFFREF-57]
|
|
+}
|
|
+
|
|
+const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF"
|
|
|
|
-var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 133, 140, 147, 155, 163, 171, 177, 183, 189, 199, 208, 219, 230, 240, 249, 262, 276, 290, 304, 320, 331, 344, 357, 371, 385, 400, 414, 428, 439, 453, 468, 485, 503, 524, 543, 562, 572, 583, 596, 607, 619, 629}
|
|
+var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 133, 140, 147, 155, 163, 171, 177, 183, 189, 199, 208, 219, 230, 240, 249, 262, 276, 290, 304, 320, 331, 344, 357, 371, 385, 400, 414, 428, 439, 453, 468, 485, 503, 524, 543, 562, 582, 602, 612, 623, 636, 647, 659, 669}
|
|
|
|
func (i RelocType) String() string {
|
|
i -= 1
|
|
diff --git a/src/cmd/link/internal/riscv64/asm.go b/src/cmd/link/internal/riscv64/asm.go
|
|
index a3f19b2..7ed45d2 100644
|
|
--- a/src/cmd/link/internal/riscv64/asm.go
|
|
+++ b/src/cmd/link/internal/riscv64/asm.go
|
|
@@ -67,7 +67,7 @@ func elfreloc1(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
|
|
// TODO(jsing): Consider generating elf.R_RISCV_CALL instead of a
|
|
// HI20/LO12_I pair.
|
|
|
|
- case objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE:
|
|
+ case objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE, objabi.R_RISCV_TLS_IE_ITYPE, objabi.R_RISCV_TLS_IE_STYPE:
|
|
// Find the text symbol for the AUIPC instruction targeted
|
|
// by this relocation.
|
|
hi20Sym := findHI20Symbol(ctxt, s.Value+int64(r.Off))
|
|
@@ -86,6 +86,10 @@ func elfreloc1(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
|
|
hiRel, loRel = elf.R_RISCV_PCREL_HI20, elf.R_RISCV_PCREL_LO12_I
|
|
case objabi.R_RISCV_PCREL_STYPE:
|
|
hiRel, loRel = elf.R_RISCV_PCREL_HI20, elf.R_RISCV_PCREL_LO12_S
|
|
+ case objabi.R_RISCV_TLS_IE_ITYPE:
|
|
+ hiRel, loRel = elf.R_RISCV_TLS_GOT_HI20, elf.R_RISCV_PCREL_LO12_I
|
|
+ case objabi.R_RISCV_TLS_IE_STYPE:
|
|
+ hiRel, loRel = elf.R_RISCV_TLS_GOT_HI20, elf.R_RISCV_PCREL_LO12_S
|
|
}
|
|
ctxt.Out.Write64(uint64(sectoff))
|
|
ctxt.Out.Write64(uint64(hiRel) | uint64(elfsym)<<32)
|
|
@@ -119,7 +123,7 @@ func archreloc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol
|
|
r.Xadd = r.Add
|
|
return val, true
|
|
|
|
- case objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE:
|
|
+ case objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE, objabi.R_RISCV_TLS_IE_ITYPE, objabi.R_RISCV_TLS_IE_STYPE:
|
|
r.Done = false
|
|
|
|
// Set up addend for eventual relocation via outer symbol.
|
|
@@ -146,6 +150,10 @@ func archreloc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol
|
|
// Nothing to do.
|
|
return val, true
|
|
|
|
+ case objabi.R_RISCV_TLS_IE_ITYPE, objabi.R_RISCV_TLS_IE_STYPE:
|
|
+ // Nothing to do.
|
|
+ return val, true
|
|
+
|
|
case objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE:
|
|
pc := s.Value + int64(r.Off)
|
|
off := ld.Symaddr(r.Sym) + r.Add - pc
|
|
@@ -202,7 +210,8 @@ func genHi20TextSymbols(ctxt *ld.Link) {
|
|
var syms []*sym.Symbol
|
|
for _, s := range ctxt.Textp {
|
|
for _, r := range s.R {
|
|
- if r.Type != objabi.R_RISCV_PCREL_ITYPE && r.Type != objabi.R_RISCV_PCREL_STYPE {
|
|
+ if r.Type != objabi.R_RISCV_PCREL_ITYPE && r.Type != objabi.R_RISCV_PCREL_STYPE &&
|
|
+ r.Type != objabi.R_RISCV_TLS_IE_ITYPE && r.Type != objabi.R_RISCV_TLS_IE_STYPE {
|
|
continue
|
|
}
|
|
sym := &sym.Symbol{
|
|
diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go
|
|
index 8f417ec..3db2c15 100644
|
|
--- a/src/cmd/link/link_test.go
|
|
+++ b/src/cmd/link/link_test.go
|
|
@@ -541,6 +541,10 @@ func TestOldLink(t *testing.T) {
|
|
|
|
testenv.MustHaveGoBuild(t)
|
|
|
|
+ if runtime.GOOS == "linux" && runtime.GOARCH == "riscv64" {
|
|
+ t.Skipf("skipping because oldlink does not handle TLS on linux/riscv64")
|
|
+ }
|
|
+
|
|
// Check that the old linker exists (we don't ship it in binary releases,
|
|
// see issue 39509).
|
|
cmd := exec.Command(testenv.GoToolPath(t), "tool", "-n", "oldlink")
|
|
--
|
|
1.8.3.1
|
|
|