]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link,cmd/internal/obj/riscv: add TLS support for linux/riscv64
authorJoel Sing <joel@sing.id.au>
Tue, 19 May 2020 08:55:10 +0000 (18:55 +1000)
committerJoel Sing <joel@sing.id.au>
Tue, 27 Oct 2020 04:20:42 +0000 (04:20 +0000)
Add support for Thread Local Storage (TLS) for linux/riscv64 with external
linking, using the initial-exec model.

Update #36641

Change-Id: I3106ef9a29cde73215830b00deff43dbec1c76e0
Reviewed-on: https://go-review.googlesource.com/c/go/+/263478
Trust: Joel Sing <joel@sing.id.au>
Run-TryBot: Joel Sing <joel@sing.id.au>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/internal/obj/riscv/obj.go
src/cmd/internal/objabi/reloctype.go
src/cmd/internal/objabi/reloctype_string.go
src/cmd/link/internal/riscv64/asm.go

index 7bd3984e51db671b0c180b1246a8591f9609ee20..da49f67138b40d0e9dae8bf0a9648c395ccb5a36 100644 (file)
@@ -1984,6 +1984,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)
index 9e2e4a150ac1b350b315555663b03a5cbac84d25..938954e07a3722f57218004b41e74d9644fdc571 100644 (file)
@@ -223,6 +223,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
index 01df4cce6244e91115f995438789827ef94b0ca4..693d9631f573059a0ed360568c6a1dec8498a980 100644 (file)
@@ -59,17 +59,19 @@ func _() {
        _ = x[R_ADDRPOWER_TOCREL_DS-49]
        _ = x[R_RISCV_PCREL_ITYPE-50]
        _ = x[R_RISCV_PCREL_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]
+       _ = x[R_RISCV_TLS_IE_ITYPE-52]
+       _ = x[R_RISCV_TLS_IE_STYPE-53]
+       _ = x[R_PCRELDBL-54]
+       _ = x[R_ADDRMIPSU-55]
+       _ = x[R_ADDRMIPSTLS-56]
+       _ = x[R_ADDRCUOFF-57]
+       _ = x[R_WASMIMPORT-58]
+       _ = x[R_XCOFFREF-59]
 }
 
-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_USEIFACER_USEIFACEMETHODR_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"
+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_USEIFACER_USEIFACEMETHODR_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, 218, 234, 245, 256, 266, 275, 288, 302, 316, 330, 346, 357, 370, 383, 397, 411, 426, 440, 454, 465, 479, 494, 511, 529, 550, 569, 588, 598, 609, 622, 633, 645, 655}
+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, 218, 234, 245, 256, 266, 275, 288, 302, 316, 330, 346, 357, 370, 383, 397, 411, 426, 440, 454, 465, 479, 494, 511, 529, 550, 569, 588, 608, 628, 638, 649, 662, 673, 685, 695}
 
 func (i RelocType) String() string {
        i -= 1
index 66c47c69f8f55d1b862488ae76cd9816cc4c43aa..c18e0540d8c313d66cff7a17f8b726628c06c0d5 100644 (file)
@@ -38,7 +38,8 @@ func genSymsLate(ctxt *ld.Link, ldr *loader.Loader) {
                relocs := ldr.Relocs(s)
                for ri := 0; ri < relocs.Count(); ri++ {
                        r := relocs.At(ri)
-                       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
                        }
                        if r.Off() == 0 && ldr.SymType(s) == sym.STEXT {
@@ -100,7 +101,7 @@ func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
                // 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.
                relocs := ldr.Relocs(s)
@@ -126,6 +127,10 @@ func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
                        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
                }
                out.Write64(uint64(sectoff))
                out.Write64(uint64(hiRel) | uint64(elfsym)<<32)
@@ -156,7 +161,7 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade
                case objabi.R_CALLRISCV:
                        return val, 0, 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:
                        return val, 2, true
                }
 
@@ -170,6 +175,16 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade
                // Nothing to do.
                return val, 0, true
 
+       case objabi.R_RISCV_TLS_IE_ITYPE, objabi.R_RISCV_TLS_IE_STYPE:
+               // TLS relocations are not currently handled for internal linking.
+               // For now, TLS is only used when cgo is in use and cgo currently
+               // requires external linking. However, we need to accept these
+               // relocations so that code containing TLS variables will link,
+               // even when they're not being used. For now, replace these
+               // instructions with EBREAK to detect accidental use.
+               const ebreakIns = 0x00100073
+               return ebreakIns<<32 | ebreakIns, 0, true
+
        case objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE:
                pc := ldr.SymValue(s) + int64(r.Off())
                off := ldr.SymValue(rs) + r.Add() - pc
@@ -222,7 +237,7 @@ func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant
 
 func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sym) (loader.ExtReloc, bool) {
        switch r.Type() {
-       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:
                return ld.ExtrelocViaOuterSym(ldr, r, s), true
        }
        return loader.ExtReloc{}, false