diff options
author | CoprDistGit <infra@openeuler.org> | 2025-04-22 00:55:42 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2025-04-22 00:55:42 +0000 |
commit | e40525e6eefe9c7d1f448fd9f9f5a2f6e9c0e632 (patch) | |
tree | 06e4ab7aad41362baa9a143eabda192466714634 /1000-all-implement-plugin-build-mode-for-riscv64.patch | |
parent | b56834d5c2724cbea1898c54e64a337ac1703bd5 (diff) |
automatic import of golang
Diffstat (limited to '1000-all-implement-plugin-build-mode-for-riscv64.patch')
-rw-r--r-- | 1000-all-implement-plugin-build-mode-for-riscv64.patch | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/1000-all-implement-plugin-build-mode-for-riscv64.patch b/1000-all-implement-plugin-build-mode-for-riscv64.patch new file mode 100644 index 0000000..be28f8f --- /dev/null +++ b/1000-all-implement-plugin-build-mode-for-riscv64.patch @@ -0,0 +1,232 @@ +From 3adb57d3e689f0c3da7a26df52e9218afb18d94f Mon Sep 17 00:00:00 2001 +From: Meng Zhuo <mengzhuo1203@gmail.com> +Date: Thu, 12 Sep 2024 20:15:56 +0800 +Subject: [PATCH] all: implement plugin build mode for riscv64 + +Change-Id: I8d7bbeebbf4a46f2fd8d630b1edbaf79b8ffccc5 +Reviewed-on: https://go-review.googlesource.com/c/go/+/420114 +Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> +Reviewed-by: Michael Knyszek <mknyszek@google.com> +Reviewed-by: Joel Sing <joel@sing.id.au> +TryBot-Bypass: Joel Sing <joel@sing.id.au> +--- + src/cmd/dist/test.go | 2 +- + src/cmd/internal/obj/riscv/obj.go | 121 +++++++++++++++++++++++++++ + src/cmd/link/internal/riscv64/asm.go | 21 ++++- + src/internal/platform/supported.go | 2 +- + src/runtime/asm_riscv64.s | 9 ++ + 5 files changed, 152 insertions(+), 3 deletions(-) + +diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go +index 0ffcabe416..b1e3929113 100644 +--- a/src/cmd/dist/test.go ++++ b/src/cmd/dist/test.go +@@ -1659,7 +1659,7 @@ func buildModeSupported(compiler, buildmode, goos, goarch string) bool { + + case "plugin": + switch platform { +- case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/loong64", "linux/s390x", "linux/ppc64le", ++ case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/loong64", "linux/riscv64", "linux/s390x", "linux/ppc64le", + "android/amd64", "android/386", + "darwin/amd64", "darwin/arm64", + "freebsd/amd64": +diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go +index 2055f4836e..44a2246e1f 100644 +--- a/src/cmd/internal/obj/riscv/obj.go ++++ b/src/cmd/internal/obj/riscv/obj.go +@@ -177,6 +177,127 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { + p.From.Offset = 0 + } + } ++ ++ if ctxt.Flag_dynlink { ++ rewriteToUseGot(ctxt, p, newprog) ++ } ++} ++ ++// Rewrite p, if necessary, to access global data via the global offset table. ++func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { ++ if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO { ++ // ADUFFxxx $offset ++ // becomes ++ // MOV runtime.duffxxx@GOT, REG_TMP ++ // ADD $offset, REG_TMP ++ // CALL REG_TMP ++ var sym *obj.LSym ++ if p.As == obj.ADUFFCOPY { ++ sym = ctxt.LookupABI("runtime.duffcopy", obj.ABIInternal) ++ } else { ++ sym = ctxt.LookupABI("runtime.duffzero", obj.ABIInternal) ++ } ++ offset := p.To.Offset ++ p.As = AMOV ++ p.From.Type = obj.TYPE_MEM ++ p.From.Name = obj.NAME_GOTREF ++ p.From.Sym = sym ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = REG_TMP ++ p.To.Name = obj.NAME_NONE ++ p.To.Offset = 0 ++ p.To.Sym = nil ++ ++ p1 := obj.Appendp(p, newprog) ++ p1.As = AADD ++ p1.From.Type = obj.TYPE_CONST ++ p1.From.Offset = offset ++ p1.To.Type = obj.TYPE_REG ++ p1.To.Reg = REG_TMP ++ ++ p2 := obj.Appendp(p1, newprog) ++ p2.As = obj.ACALL ++ p2.To.Type = obj.TYPE_REG ++ p2.To.Reg = REG_TMP ++ } ++ ++ // We only care about global data: NAME_EXTERN means a global ++ // symbol in the Go sense and p.Sym.Local is true for a few internally ++ // defined symbols. ++ if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { ++ // MOV $sym, Rx becomes MOV sym@GOT, Rx ++ // MOV $sym+<off>, Rx becomes MOV sym@GOT, Rx; ADD <off>, Rx ++ if p.As != AMOV { ++ ctxt.Diag("don't know how to handle TYPE_ADDR in %v with -dynlink", p) ++ } ++ if p.To.Type != obj.TYPE_REG { ++ ctxt.Diag("don't know how to handle LD instruction to non-register in %v with -dynlink", p) ++ } ++ p.From.Type = obj.TYPE_MEM ++ p.From.Name = obj.NAME_GOTREF ++ if p.From.Offset != 0 { ++ q := obj.Appendp(p, newprog) ++ q.As = AADD ++ q.From.Type = obj.TYPE_CONST ++ q.From.Offset = p.From.Offset ++ q.To = p.To ++ p.From.Offset = 0 ++ } ++ ++ } ++ ++ if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN { ++ ctxt.Diag("don't know how to handle %v with -dynlink", p) ++ } ++ ++ var source *obj.Addr ++ // MOVx sym, Ry becomes MOV sym@GOT, X31; MOVx (X31), Ry ++ // MOVx Ry, sym becomes MOV sym@GOT, X31; MOV Ry, (X31) ++ // An addition may be inserted between the two MOVs if there is an offset. ++ if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { ++ if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { ++ ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p) ++ } ++ source = &p.From ++ } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { ++ source = &p.To ++ } else { ++ return ++ } ++ if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP { ++ return ++ } ++ if source.Sym.Type == objabi.STLSBSS { ++ return ++ } ++ if source.Type != obj.TYPE_MEM { ++ ctxt.Diag("don't know how to handle %v with -dynlink", p) ++ } ++ p1 := obj.Appendp(p, newprog) ++ p1.As = AMOV ++ p1.From.Type = obj.TYPE_MEM ++ p1.From.Sym = source.Sym ++ p1.From.Name = obj.NAME_GOTREF ++ p1.To.Type = obj.TYPE_REG ++ p1.To.Reg = REG_TMP ++ ++ p2 := obj.Appendp(p1, newprog) ++ p2.As = p.As ++ p2.From = p.From ++ p2.To = p.To ++ if p.From.Name == obj.NAME_EXTERN { ++ p2.From.Reg = REG_TMP ++ p2.From.Name = obj.NAME_NONE ++ p2.From.Sym = nil ++ } else if p.To.Name == obj.NAME_EXTERN { ++ p2.To.Reg = REG_TMP ++ p2.To.Name = obj.NAME_NONE ++ p2.To.Sym = nil ++ } else { ++ return ++ } ++ obj.Nopout(p) ++ + } + + // addrToReg extracts the register from an Addr, handling special Addr.Names. +diff --git a/src/cmd/link/internal/riscv64/asm.go b/src/cmd/link/internal/riscv64/asm.go +index 6a4dd01240..a9583d21aa 100644 +--- a/src/cmd/link/internal/riscv64/asm.go ++++ b/src/cmd/link/internal/riscv64/asm.go +@@ -20,7 +20,26 @@ import ( + // fakeLabelName matches the RISCV_FAKE_LABEL_NAME from binutils. + const fakeLabelName = ".L0 " + +-func gentext(ctxt *ld.Link, ldr *loader.Loader) {} ++func gentext(ctxt *ld.Link, ldr *loader.Loader) { ++ initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt) ++ if initfunc == nil { ++ return ++ } ++ ++ // Emit the following function: ++ // ++ // go.link.addmoduledatainit: ++ // auipc a0, %pcrel_hi(local.moduledata) ++ // addi a0, %pcrel_lo(local.moduledata) ++ // j runtime.addmoduledata ++ ++ sz := initfunc.AddSymRef(ctxt.Arch, ctxt.Moduledata, 0, objabi.R_RISCV_PCREL_ITYPE, 8) ++ initfunc.SetUint32(ctxt.Arch, sz-8, 0x00000517) // auipc a0, %pcrel_hi(local.moduledata) ++ initfunc.SetUint32(ctxt.Arch, sz-4, 0x00050513) // addi a0, %pcrel_lo(local.moduledata) ++ ++ sz = initfunc.AddSymRef(ctxt.Arch, addmoduledata, 0, objabi.R_RISCV_JAL, 4) ++ initfunc.SetUint32(ctxt.Arch, sz-4, 0x0000006f) // j runtime.addmoduledata ++} + + func findHI20Reloc(ldr *loader.Loader, s loader.Sym, val int64) *loader.Reloc { + outer := ldr.OuterSym(s) +diff --git a/src/internal/platform/supported.go b/src/internal/platform/supported.go +index a774247e6b..bad1a6c9c4 100644 +--- a/src/internal/platform/supported.go ++++ b/src/internal/platform/supported.go +@@ -207,7 +207,7 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { + + case "plugin": + switch platform { +- case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/loong64", "linux/s390x", "linux/ppc64le", ++ case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/loong64", "linux/riscv64", "linux/s390x", "linux/ppc64le", + "android/amd64", "android/386", + "darwin/amd64", "darwin/arm64", + "freebsd/amd64": +diff --git a/src/runtime/asm_riscv64.s b/src/runtime/asm_riscv64.s +index 491635b1cf..231564aca2 100644 +--- a/src/runtime/asm_riscv64.s ++++ b/src/runtime/asm_riscv64.s +@@ -542,6 +542,15 @@ TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0 + // traceback from goexit1 must hit code range of goexit + MOV ZERO, ZERO // NOP + ++ ++// This is called from .init_array and follows the platform, not the Go ABI. ++TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0 ++ // Use X31 as it is a scratch register in both the Go ABI and psABI. ++ MOV runtime·lastmoduledatap(SB), X31 ++ MOV X10, moduledata_next(X31) ++ MOV X10, runtime·lastmoduledatap(SB) ++ RET ++ + // func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr) + // See cgocall.go for more details. + TEXT ·cgocallback(SB),NOSPLIT,$24-24 +-- +2.48.1.windows.1 + |