From 3a63d04d2edcbdb0937d775e852692279f73a2e2 Mon Sep 17 00:00:00 2001 From: Joel Sing Date: Tue, 19 May 2020 18:55:10 +1000 Subject: 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. Update #36641 Change-Id: I3106ef9a29cde73215830b00deff43dbec1c76e0 Reviewed-on: https://go-review.googlesource.com/c/go/+/263478 Trust: Joel Sing Run-TryBot: Joel Sing TryBot-Result: Go Bot Reviewed-by: Cherry Zhang --- src/cmd/internal/obj/riscv/obj.go | 7 +++++++ src/cmd/internal/objabi/reloctype.go | 8 ++++++++ src/cmd/internal/objabi/reloctype_string.go | 18 ++++++++++-------- src/cmd/link/internal/riscv64/asm.go | 23 +++++++++++++++++++---- 4 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go index 7bd3984e51..da49f67138 100644 --- a/src/cmd/internal/obj/riscv/obj.go +++ b/src/cmd/internal/obj/riscv/obj.go @@ -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) diff --git a/src/cmd/internal/objabi/reloctype.go b/src/cmd/internal/objabi/reloctype.go index 9e2e4a150a..938954e07a 100644 --- a/src/cmd/internal/objabi/reloctype.go +++ b/src/cmd/internal/objabi/reloctype.go @@ -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 diff --git a/src/cmd/internal/objabi/reloctype_string.go b/src/cmd/internal/objabi/reloctype_string.go index 01df4cce62..693d9631f5 100644 --- a/src/cmd/internal/objabi/reloctype_string.go +++ b/src/cmd/internal/objabi/reloctype_string.go @@ -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 diff --git a/src/cmd/link/internal/riscv64/asm.go b/src/cmd/link/internal/riscv64/asm.go index 66c47c69f8..c18e0540d8 100644 --- a/src/cmd/link/internal/riscv64/asm.go +++ b/src/cmd/link/internal/riscv64/asm.go @@ -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 -- cgit v1.2.3-54-g00ecf