// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package riscv64

import (
	"cmd/internal/obj/riscv"
	"cmd/internal/objabi"
	"cmd/internal/sys"
	"cmd/link/internal/ld"
	"cmd/link/internal/loader"
	"cmd/link/internal/sym"
	"debug/elf"
	"fmt"
	"log"
	"sort"
)

// fakeLabelName matches the RISCV_FAKE_LABEL_NAME from binutils.
const fakeLabelName = ".L0 "

func gentext(ctxt *ld.Link, ldr *loader.Loader) {}

func findHI20Reloc(ldr *loader.Loader, s loader.Sym, val int64) *loader.Reloc {
	outer := ldr.OuterSym(s)
	if outer == 0 {
		return nil
	}
	relocs := ldr.Relocs(outer)
	start := sort.Search(relocs.Count(), func(i int) bool { return ldr.SymValue(outer)+int64(relocs.At(i).Off()) >= val })
	for idx := start; idx < relocs.Count(); idx++ {
		r := relocs.At(idx)
		if ldr.SymValue(outer)+int64(r.Off()) != val {
			break
		}
		if r.Type() == objabi.R_RISCV_GOT_HI20 || r.Type() == objabi.R_RISCV_PCREL_HI20 {
			return &r
		}
	}
	return nil
}

func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc, rIdx int) bool {
	targ := r.Sym()

	var targType sym.SymKind
	if targ != 0 {
		targType = ldr.SymType(targ)
	}

	switch r.Type() {
	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_RISCV_CALL),
		objabi.ElfRelocOffset + objabi.RelocType(elf.R_RISCV_CALL_PLT):

		if targType == sym.SDYNIMPORT {
			addpltsym(target, ldr, syms, targ)
			su := ldr.MakeSymbolUpdater(s)
			su.SetRelocSym(rIdx, syms.PLT)
			su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymPlt(targ)))
		}
		if targType == 0 || targType == sym.SXREF {
			ldr.Errorf(s, "unknown symbol %s in RISCV call", ldr.SymName(targ))
		}
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_RISCV_CALL)
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_RISCV_GOT_HI20):
		if targType != sym.SDYNIMPORT {
			// TODO(jsing): Could convert to non-GOT reference.
		}

		ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_RISCV_64))
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_RISCV_GOT_HI20)
		su.SetRelocSym(rIdx, syms.GOT)
		su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_RISCV_PCREL_HI20):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_RISCV_PCREL_HI20)
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_RISCV_PCREL_LO12_I):
		if r.Add() != 0 {
			ldr.Errorf(s, "R_RISCV_PCREL_LO12_I with non-zero addend")
		}
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_RISCV_PCREL_LO12_I)
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_RISCV_PCREL_LO12_S):
		if r.Add() != 0 {
			ldr.Errorf(s, "R_RISCV_PCREL_LO12_S with non-zero addend")
		}
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_RISCV_PCREL_LO12_S)
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_RISCV_RVC_BRANCH):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_RISCV_RVC_BRANCH)
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_RISCV_RVC_JUMP):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_RISCV_RVC_JUMP)
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_RISCV_BRANCH):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_RISCV_BRANCH)
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_RISCV_RELAX):
		// Ignore relaxations, at least for now.
		return true

	default:
		if r.Type() >= objabi.ElfRelocOffset {
			ldr.Errorf(s, "unexpected relocation type %d (%s)", r.Type(), sym.RelocName(target.Arch, r.Type()))
			return false
		}
	}

	// Reread the reloc to incorporate any changes in type above.
	relocs := ldr.Relocs(s)
	r = relocs.At(rIdx)

	switch r.Type() {
	case objabi.R_RISCV_CALL:
		if targType != sym.SDYNIMPORT {
			// nothing to do, the relocation will be laid out in reloc
			return true
		}
		if target.IsExternal() {
			// External linker will do this relocation.
			return true
		}
		// Internal linking.
		if r.Add() != 0 {
			ldr.Errorf(s, "PLT reference with non-zero addend (%v)", r.Add())
		}
		// Build a PLT entry and change the relocation target to that entry.
		addpltsym(target, ldr, syms, targ)
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocSym(rIdx, syms.PLT)
		su.SetRelocAdd(rIdx, int64(ldr.SymPlt(targ)))

		return true
	}

	return false
}

func genSymsLate(ctxt *ld.Link, ldr *loader.Loader) {
	if ctxt.LinkMode != ld.LinkExternal {
		return
	}

	// Generate a local text symbol for each relocation target, as the
	// R_RISCV_PCREL_LO12_* relocations generated by elfreloc1 need it.
	if ctxt.Textp == nil {
		log.Fatal("genSymsLate called before Textp has been assigned")
	}
	var hi20Syms []loader.Sym
	for _, s := range ctxt.Textp {
		relocs := ldr.Relocs(s)
		for ri := 0; ri < relocs.Count(); ri++ {
			r := relocs.At(ri)
			if r.Type() != objabi.R_RISCV_CALL && r.Type() != objabi.R_RISCV_PCREL_ITYPE &&
				r.Type() != objabi.R_RISCV_PCREL_STYPE && r.Type() != objabi.R_RISCV_TLS_IE {
				continue
			}
			if r.Off() == 0 && ldr.SymType(s) == sym.STEXT {
				// Use the symbol for the function instead of creating
				// an overlapping symbol.
				continue
			}

			// TODO(jsing): Consider generating ELF symbols without needing
			// loader symbols, in order to reduce memory consumption. This
			// would require changes to genelfsym so that it called
			// putelfsym and putelfsyment as appropriate.
			sb := ldr.MakeSymbolBuilder(fakeLabelName)
			sb.SetType(sym.STEXT)
			sb.SetValue(ldr.SymValue(s) + int64(r.Off()))
			sb.SetLocal(true)
			sb.SetReachable(true)
			sb.SetVisibilityHidden(true)
			sb.SetSect(ldr.SymSect(s))
			if outer := ldr.OuterSym(s); outer != 0 {
				ldr.AddInteriorSym(outer, sb.Sym())
			}
			hi20Syms = append(hi20Syms, sb.Sym())
		}
	}
	ctxt.Textp = append(ctxt.Textp, hi20Syms...)
	ldr.SortSyms(ctxt.Textp)
}

func findHI20Symbol(ctxt *ld.Link, ldr *loader.Loader, val int64) loader.Sym {
	idx := sort.Search(len(ctxt.Textp), func(i int) bool { return ldr.SymValue(ctxt.Textp[i]) >= val })
	if idx >= len(ctxt.Textp) {
		return 0
	}
	if s := ctxt.Textp[idx]; ldr.SymValue(s) == val && ldr.SymType(s) == sym.STEXT {
		return s
	}
	return 0
}

func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, ri int, sectoff int64) bool {
	elfsym := ld.ElfSymForReloc(ctxt, r.Xsym)
	switch r.Type {
	case objabi.R_ADDR, objabi.R_DWARFSECREF:
		out.Write64(uint64(sectoff))
		switch r.Size {
		case 4:
			out.Write64(uint64(elf.R_RISCV_32) | uint64(elfsym)<<32)
		case 8:
			out.Write64(uint64(elf.R_RISCV_64) | uint64(elfsym)<<32)
		default:
			ld.Errorf(nil, "unknown size %d for %v relocation", r.Size, r.Type)
			return false
		}
		out.Write64(uint64(r.Xadd))

	case objabi.R_RISCV_JAL, objabi.R_RISCV_JAL_TRAMP:
		out.Write64(uint64(sectoff))
		out.Write64(uint64(elf.R_RISCV_JAL) | uint64(elfsym)<<32)
		out.Write64(uint64(r.Xadd))

	case objabi.R_RISCV_CALL, objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE, objabi.R_RISCV_TLS_IE:
		// Find the text symbol for the AUIPC instruction targeted
		// by this relocation.
		relocs := ldr.Relocs(s)
		offset := int64(relocs.At(ri).Off())
		hi20Sym := findHI20Symbol(ctxt, ldr, ldr.SymValue(s)+offset)
		if hi20Sym == 0 {
			ld.Errorf(nil, "failed to find text symbol for HI20 relocation at %d (%x)", sectoff, ldr.SymValue(s)+offset)
			return false
		}
		hi20ElfSym := ld.ElfSymForReloc(ctxt, hi20Sym)

		// Emit two relocations - a R_RISCV_PCREL_HI20 relocation and a
		// corresponding R_RISCV_PCREL_LO12_I or R_RISCV_PCREL_LO12_S relocation.
		// Note that the LO12 relocation must point to a target that has a valid
		// HI20 PC-relative relocation text symbol, which in turn points to the
		// given symbol. For further details see section 8.4.9 of the RISC-V ABIs
		// Specification:
		//
		//  https://github.com/riscv-non-isa/riscv-elf-psabi-doc/releases/download/v1.0/riscv-abi.pdf
		//
		var hiRel, loRel elf.R_RISCV
		switch r.Type {
		case objabi.R_RISCV_CALL, objabi.R_RISCV_PCREL_ITYPE:
			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:
			hiRel, loRel = elf.R_RISCV_TLS_GOT_HI20, elf.R_RISCV_PCREL_LO12_I
		}
		out.Write64(uint64(sectoff))
		out.Write64(uint64(hiRel) | uint64(elfsym)<<32)
		out.Write64(uint64(r.Xadd))
		out.Write64(uint64(sectoff + 4))
		out.Write64(uint64(loRel) | uint64(hi20ElfSym)<<32)
		out.Write64(uint64(0))

	case objabi.R_RISCV_TLS_LE:
		out.Write64(uint64(sectoff))
		out.Write64(uint64(elf.R_RISCV_TPREL_HI20) | uint64(elfsym)<<32)
		out.Write64(uint64(r.Xadd))
		out.Write64(uint64(sectoff + 4))
		out.Write64(uint64(elf.R_RISCV_TPREL_LO12_I) | uint64(elfsym)<<32)
		out.Write64(uint64(r.Xadd))

	default:
		return false
	}

	return true
}

func elfsetupplt(ctxt *ld.Link, ldr *loader.Loader, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) {
	if plt.Size() != 0 {
		return
	}
	if gotplt.Size() != 0 {
		ctxt.Errorf(gotplt.Sym(), "got.plt is not empty")
	}

	// See section 8.4.6 of the RISC-V ABIs Specification:
	//
	//  https://github.com/riscv-non-isa/riscv-elf-psabi-doc/releases/download/v1.0/riscv-abi.pdf
	//
	// 1:   auipc  t2, %pcrel_hi(.got.plt)
	//      sub    t1, t1, t3               # shifted .got.plt offset + hdr size + 12
	//      l[w|d] t3, %pcrel_lo(1b)(t2)    # _dl_runtime_resolve
	//      addi   t1, t1, -(hdr size + 12) # shifted .got.plt offset
	//      addi   t0, t2, %pcrel_lo(1b)    # &.got.plt
	//      srli   t1, t1, log2(16/PTRSIZE) # .got.plt offset
	//      l[w|d] t0, PTRSIZE(t0)          # link map
	//      jr     t3

	plt.AddSymRef(ctxt.Arch, gotplt.Sym(), 0, objabi.R_RISCV_PCREL_HI20, 4)
	plt.SetUint32(ctxt.Arch, plt.Size()-4, 0x00000397) // auipc   t2,0x0

	sb := ldr.MakeSymbolBuilder(fakeLabelName)
	sb.SetType(sym.STEXT)
	sb.SetValue(ldr.SymValue(plt.Sym()) + plt.Size() - 4)
	sb.SetLocal(true)
	sb.SetReachable(true)
	sb.SetVisibilityHidden(true)
	plt.AddInteriorSym(sb.Sym())

	plt.AddUint32(ctxt.Arch, 0x41c30333) // sub     t1,t1,t3

	plt.AddSymRef(ctxt.Arch, sb.Sym(), 0, objabi.R_RISCV_PCREL_LO12_I, 4)
	plt.SetUint32(ctxt.Arch, plt.Size()-4, 0x0003be03) // ld      t3,0(t2)

	plt.AddUint32(ctxt.Arch, 0xfd430313) // addi    t1,t1,-44

	plt.AddSymRef(ctxt.Arch, sb.Sym(), 0, objabi.R_RISCV_PCREL_LO12_I, 4)
	plt.SetUint32(ctxt.Arch, plt.Size()-4, 0x00038293) // addi    t0,t2,0

	plt.AddUint32(ctxt.Arch, 0x00135313) // srli    t1,t1,0x1
	plt.AddUint32(ctxt.Arch, 0x0082b283) // ld      t0,8(t0)
	plt.AddUint32(ctxt.Arch, 0x00008e02) // jr      t3

	gotplt.AddAddrPlus(ctxt.Arch, dynamic, 0) // got.plt[0] = _dl_runtime_resolve
	gotplt.AddUint64(ctxt.Arch, 0)            // got.plt[1] = link map
}

func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
	if ldr.SymPlt(s) >= 0 {
		return
	}

	ld.Adddynsym(ldr, target, syms, s)

	plt := ldr.MakeSymbolUpdater(syms.PLT)
	gotplt := ldr.MakeSymbolUpdater(syms.GOTPLT)
	rela := ldr.MakeSymbolUpdater(syms.RelaPLT)
	if plt.Size() == 0 {
		panic("plt is not set up")
	}

	// See section 8.4.6 of the RISC-V ABIs Specification:
	//
	//  https://github.com/riscv-non-isa/riscv-elf-psabi-doc/releases/download/v1.0/riscv-abi.pdf
	//
	// 1:  auipc   t3, %pcrel_hi(function@.got.plt)
	//     l[w|d]  t3, %pcrel_lo(1b)(t3)
	//     jalr    t1, t3
	//     nop

	plt.AddSymRef(target.Arch, gotplt.Sym(), gotplt.Size(), objabi.R_RISCV_PCREL_HI20, 4)
	plt.SetUint32(target.Arch, plt.Size()-4, 0x00000e17) // auipc   t3,0x0

	sb := ldr.MakeSymbolBuilder(fakeLabelName)
	sb.SetType(sym.STEXT)
	sb.SetValue(ldr.SymValue(plt.Sym()) + plt.Size() - 4)
	sb.SetLocal(true)
	sb.SetReachable(true)
	sb.SetVisibilityHidden(true)
	plt.AddInteriorSym(sb.Sym())

	plt.AddSymRef(target.Arch, sb.Sym(), 0, objabi.R_RISCV_PCREL_LO12_I, 4)
	plt.SetUint32(target.Arch, plt.Size()-4, 0x000e3e03) // ld      t3,0(t3)
	plt.AddUint32(target.Arch, 0x000e0367)               // jalr    t1,t3
	plt.AddUint32(target.Arch, 0x00000001)               // nop

	ldr.SetPlt(s, int32(plt.Size()-16))

	// add to got.plt: pointer to plt[0]
	gotplt.AddAddrPlus(target.Arch, plt.Sym(), 0)

	// rela
	rela.AddAddrPlus(target.Arch, gotplt.Sym(), gotplt.Size()-8)
	sDynid := ldr.SymDynid(s)

	rela.AddUint64(target.Arch, elf.R_INFO(uint32(sDynid), uint32(elf.R_RISCV_JUMP_SLOT)))
	rela.AddUint64(target.Arch, 0)
}

func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool {
	log.Fatalf("machoreloc1 not implemented")
	return false
}

func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc, s loader.Sym, val int64) (o int64, nExtReloc int, ok bool) {
	rs := r.Sym()
	pc := ldr.SymValue(s) + int64(r.Off())

	// If the call points to a trampoline, see if we can reach the symbol
	// directly. This situation can occur when the relocation symbol is
	// not assigned an address until after the trampolines are generated.
	if r.Type() == objabi.R_RISCV_JAL_TRAMP {
		relocs := ldr.Relocs(rs)
		if relocs.Count() != 1 {
			ldr.Errorf(s, "trampoline %v has %d relocations", ldr.SymName(rs), relocs.Count())
		}
		tr := relocs.At(0)
		if tr.Type() != objabi.R_RISCV_CALL {
			ldr.Errorf(s, "trampoline %v has unexpected relocation %v", ldr.SymName(rs), tr.Type())
		}
		trs := tr.Sym()
		if ldr.SymValue(trs) != 0 && ldr.SymType(trs) != sym.SDYNIMPORT && ldr.SymType(trs) != sym.SUNDEFEXT {
			trsOff := ldr.SymValue(trs) + tr.Add() - pc
			if trsOff >= -(1<<20) && trsOff < (1<<20) {
				r.SetType(objabi.R_RISCV_JAL)
				r.SetSym(trs)
				r.SetAdd(tr.Add())
				rs = trs
			}
		}

	}

	if target.IsExternal() {
		switch r.Type() {
		case objabi.R_RISCV_JAL, objabi.R_RISCV_JAL_TRAMP:
			return val, 1, true

		case objabi.R_RISCV_CALL, objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE, objabi.R_RISCV_TLS_IE, objabi.R_RISCV_TLS_LE:
			return val, 2, true
		}

		return val, 0, false
	}

	off := ldr.SymValue(rs) + r.Add() - pc

	switch r.Type() {
	case objabi.R_RISCV_JAL, objabi.R_RISCV_JAL_TRAMP:
		// Generate instruction immediates.
		imm, err := riscv.EncodeJImmediate(off)
		if err != nil {
			ldr.Errorf(s, "cannot encode J-type instruction relocation offset for %s: %v", ldr.SymName(rs), err)
		}
		immMask := int64(riscv.JTypeImmMask)

		val = (val &^ immMask) | int64(imm)

		return val, 0, true

	case objabi.R_RISCV_TLS_IE:
		log.Fatalf("cannot handle R_RISCV_TLS_IE (sym %s) when linking internally", ldr.SymName(s))
		return val, 0, false

	case objabi.R_RISCV_TLS_LE:
		// Generate LUI and ADDIW instruction immediates.
		off := r.Add()

		low, high, err := riscv.Split32BitImmediate(off)
		if err != nil {
			ldr.Errorf(s, "relocation does not fit in 32-bits: %d", off)
		}

		luiImm, err := riscv.EncodeUImmediate(high)
		if err != nil {
			ldr.Errorf(s, "cannot encode R_RISCV_TLS_LE LUI relocation offset for %s: %v", ldr.SymName(rs), err)
		}

		addiwImm, err := riscv.EncodeIImmediate(low)
		if err != nil {
			ldr.Errorf(s, "cannot encode R_RISCV_TLS_LE I-type instruction relocation offset for %s: %v", ldr.SymName(rs), err)
		}

		lui := int64(uint32(val))
		addiw := int64(uint32(val >> 32))

		lui = (lui &^ riscv.UTypeImmMask) | int64(uint32(luiImm))
		addiw = (addiw &^ riscv.ITypeImmMask) | int64(uint32(addiwImm))

		return addiw<<32 | lui, 0, true

	case objabi.R_RISCV_BRANCH:
		pc := ldr.SymValue(s) + int64(r.Off())
		off := ldr.SymValue(rs) + r.Add() - pc

		imm, err := riscv.EncodeBImmediate(off)
		if err != nil {
			ldr.Errorf(s, "cannot encode B-type instruction relocation offset for %s: %v", ldr.SymName(rs), err)
		}
		ins := (int64(uint32(val)) &^ riscv.BTypeImmMask) | int64(uint32(imm))

		return ins, 0, true

	case objabi.R_RISCV_RVC_BRANCH, objabi.R_RISCV_RVC_JUMP:
		pc := ldr.SymValue(s) + int64(r.Off())
		off := ldr.SymValue(rs) + r.Add() - pc

		var err error
		var imm, immMask int64
		switch r.Type() {
		case objabi.R_RISCV_RVC_BRANCH:
			immMask = riscv.CBTypeImmMask
			imm, err = riscv.EncodeCBImmediate(off)
			if err != nil {
				ldr.Errorf(s, "cannot encode CB-type instruction relocation offset for %s: %v", ldr.SymName(rs), err)
			}
		case objabi.R_RISCV_RVC_JUMP:
			immMask = riscv.CJTypeImmMask
			imm, err = riscv.EncodeCJImmediate(off)
			if err != nil {
				ldr.Errorf(s, "cannot encode CJ-type instruction relocation offset for %s: %v", ldr.SymName(rs), err)
			}
		default:
			panic(fmt.Sprintf("unknown relocation type: %v", r.Type()))
		}

		ins := (int64(uint16(val)) &^ immMask) | int64(uint16(imm))

		return ins, 0, true

	case objabi.R_RISCV_GOT_HI20, objabi.R_RISCV_PCREL_HI20:
		pc := ldr.SymValue(s) + int64(r.Off())
		off := ldr.SymValue(rs) + r.Add() - pc

		// Generate AUIPC immediates.
		_, high, err := riscv.Split32BitImmediate(off)
		if err != nil {
			ldr.Errorf(s, "relocation does not fit in 32-bits: %d", off)
		}

		auipcImm, err := riscv.EncodeUImmediate(high)
		if err != nil {
			ldr.Errorf(s, "cannot encode R_RISCV_PCREL_ AUIPC relocation offset for %s: %v", ldr.SymName(rs), err)
		}

		auipc := int64(uint32(val))
		auipc = (auipc &^ riscv.UTypeImmMask) | int64(uint32(auipcImm))

		return auipc, 0, true

	case objabi.R_RISCV_PCREL_LO12_I, objabi.R_RISCV_PCREL_LO12_S:
		hi20Reloc := findHI20Reloc(ldr, rs, ldr.SymValue(rs))
		if hi20Reloc == nil {
			ldr.Errorf(s, "missing HI20 relocation for LO12 relocation with %s (%d)", ldr.SymName(rs), rs)
		}

		pc := ldr.SymValue(s) + int64(hi20Reloc.Off())
		off := ldr.SymValue(hi20Reloc.Sym()) + hi20Reloc.Add() - pc

		low, _, err := riscv.Split32BitImmediate(off)
		if err != nil {
			ldr.Errorf(s, "relocation does not fit in 32-bits: %d", off)
		}

		var imm, immMask int64
		switch r.Type() {
		case objabi.R_RISCV_PCREL_LO12_I:
			immMask = riscv.ITypeImmMask
			imm, err = riscv.EncodeIImmediate(low)
			if err != nil {
				ldr.Errorf(s, "cannot encode objabi.R_RISCV_PCREL_LO12_I I-type instruction relocation offset for %s: %v", ldr.SymName(rs), err)
			}
		case objabi.R_RISCV_PCREL_LO12_S:
			immMask = riscv.STypeImmMask
			imm, err = riscv.EncodeSImmediate(low)
			if err != nil {
				ldr.Errorf(s, "cannot encode R_RISCV_PCREL_LO12_S S-type instruction relocation offset for %s: %v", ldr.SymName(rs), err)
			}
		default:
			panic(fmt.Sprintf("unknown relocation type: %v", r.Type()))
		}

		ins := int64(uint32(val))
		ins = (ins &^ immMask) | int64(uint32(imm))
		return ins, 0, true

	case objabi.R_RISCV_CALL, objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE:
		// Generate AUIPC and second instruction immediates.
		low, high, err := riscv.Split32BitImmediate(off)
		if err != nil {
			ldr.Errorf(s, "pc-relative relocation does not fit in 32 bits: %d", off)
		}

		auipcImm, err := riscv.EncodeUImmediate(high)
		if err != nil {
			ldr.Errorf(s, "cannot encode AUIPC relocation offset for %s: %v", ldr.SymName(rs), err)
		}

		var secondImm, secondImmMask int64
		switch r.Type() {
		case objabi.R_RISCV_CALL, objabi.R_RISCV_PCREL_ITYPE:
			secondImmMask = riscv.ITypeImmMask
			secondImm, err = riscv.EncodeIImmediate(low)
			if err != nil {
				ldr.Errorf(s, "cannot encode I-type instruction relocation offset for %s: %v", ldr.SymName(rs), err)
			}
		case objabi.R_RISCV_PCREL_STYPE:
			secondImmMask = riscv.STypeImmMask
			secondImm, err = riscv.EncodeSImmediate(low)
			if err != nil {
				ldr.Errorf(s, "cannot encode S-type instruction relocation offset for %s: %v", ldr.SymName(rs), err)
			}
		default:
			panic(fmt.Sprintf("unknown relocation type: %v", r.Type()))
		}

		auipc := int64(uint32(val))
		second := int64(uint32(val >> 32))

		auipc = (auipc &^ riscv.UTypeImmMask) | int64(uint32(auipcImm))
		second = (second &^ secondImmMask) | int64(uint32(secondImm))

		return second<<32 | auipc, 0, true
	}

	return val, 0, false
}

func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64, []byte) int64 {
	log.Fatalf("archrelocvariant")
	return -1
}

func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sym) (loader.ExtReloc, bool) {
	switch r.Type() {
	case objabi.R_RISCV_JAL, objabi.R_RISCV_JAL_TRAMP:
		return ld.ExtrelocSimple(ldr, r), true

	case objabi.R_RISCV_CALL, objabi.R_RISCV_PCREL_ITYPE, objabi.R_RISCV_PCREL_STYPE, objabi.R_RISCV_TLS_IE, objabi.R_RISCV_TLS_LE:
		return ld.ExtrelocViaOuterSym(ldr, r, s), true
	}
	return loader.ExtReloc{}, false
}

func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) {
	relocs := ldr.Relocs(s)
	r := relocs.At(ri)

	switch r.Type() {
	case objabi.R_RISCV_JAL:
		pc := ldr.SymValue(s) + int64(r.Off())
		off := ldr.SymValue(rs) + r.Add() - pc

		// Relocation symbol has an address and is directly reachable,
		// therefore there is no need for a trampoline.
		if ldr.SymValue(rs) != 0 && off >= -(1<<20) && off < (1<<20) && (*ld.FlagDebugTramp <= 1 || ldr.SymPkg(s) == ldr.SymPkg(rs)) {
			break
		}

		// Relocation symbol is too far for a direct call or has not
		// yet been given an address. See if an existing trampoline is
		// reachable and if so, reuse it. Otherwise we need to create
		// a new trampoline.
		var tramp loader.Sym
		for i := 0; ; i++ {
			oName := ldr.SymName(rs)
			name := fmt.Sprintf("%s-tramp%d", oName, i)
			if r.Add() != 0 {
				name = fmt.Sprintf("%s%+x-tramp%d", oName, r.Add(), i)
			}
			tramp = ldr.LookupOrCreateSym(name, int(ldr.SymVersion(rs)))
			ldr.SetAttrReachable(tramp, true)
			if ldr.SymType(tramp) == sym.SDYNIMPORT {
				// Do not reuse trampoline defined in other module.
				continue
			}
			if oName == "runtime.deferreturn" {
				ldr.SetIsDeferReturnTramp(tramp, true)
			}
			if ldr.SymValue(tramp) == 0 {
				// Either trampoline does not exist or we found one
				// that does not have an address assigned and will be
				// laid down immediately after the current function.
				break
			}

			trampOff := ldr.SymValue(tramp) - (ldr.SymValue(s) + int64(r.Off()))
			if trampOff >= -(1<<20) && trampOff < (1<<20) {
				// An existing trampoline that is reachable.
				break
			}
		}
		if ldr.SymType(tramp) == 0 {
			trampb := ldr.MakeSymbolUpdater(tramp)
			ctxt.AddTramp(trampb)
			genCallTramp(ctxt.Arch, ctxt.LinkMode, ldr, trampb, rs, int64(r.Add()))
		}
		sb := ldr.MakeSymbolUpdater(s)
		if ldr.SymValue(rs) == 0 {
			// In this case the target symbol has not yet been assigned an
			// address, so we have to assume a trampoline is required. Mark
			// this as a call via a trampoline so that we can potentially
			// switch to a direct call during relocation.
			sb.SetRelocType(ri, objabi.R_RISCV_JAL_TRAMP)
		}
		relocs := sb.Relocs()
		r := relocs.At(ri)
		r.SetSym(tramp)
		r.SetAdd(0)

	case objabi.R_RISCV_CALL:
		// Nothing to do, already using AUIPC+JALR.

	default:
		ctxt.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type(), sym.RelocName(ctxt.Arch, r.Type()))
	}
}

func genCallTramp(arch *sys.Arch, linkmode ld.LinkMode, ldr *loader.Loader, tramp *loader.SymbolBuilder, target loader.Sym, offset int64) {
	tramp.AddUint32(arch, 0x00000f97) // AUIPC	$0, X31
	tramp.AddUint32(arch, 0x000f8067) // JALR	X0, (X31)

	r, _ := tramp.AddRel(objabi.R_RISCV_CALL)
	r.SetSiz(8)
	r.SetSym(target)
	r.SetAdd(offset)
}
