From 4e3deae96d605cc5be6759b6ffdf659006e4c3a4 Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle <michael.hudson@canonical.com> Date: Wed, 24 Jun 2015 22:31:24 +1200 Subject: [PATCH] cmd/link, runtime: arm64 implementation of addmoduledata Change-Id: I62fb5b20d7caa51b77560a4bfb74a39f17089805 Reviewed-on: https://go-review.googlesource.com/13999 Reviewed-by: Russ Cox <rsc@golang.org> --- src/cmd/link/internal/arm64/asm.go | 53 +++++++++++++++++++++++++++++- src/runtime/asm_arm64.s | 11 +++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go index 8517a90004..2e974cc3f4 100644 --- a/src/cmd/link/internal/arm64/asm.go +++ b/src/cmd/link/internal/arm64/asm.go @@ -38,7 +38,58 @@ import ( "log" ) -func gentext() {} +func gentext() { + if !ld.DynlinkingGo() { + return + } + addmoduledata := ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0) + if addmoduledata.Type == obj.STEXT { + // we're linking a module containing the runtime -> no need for + // an init function + return + } + addmoduledata.Reachable = true + initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0) + initfunc.Type = obj.STEXT + initfunc.Local = true + initfunc.Reachable = true + o := func(op uint32) { + ld.Adduint32(ld.Ctxt, initfunc, op) + } + // 0000000000000000 <local.dso_init>: + // 0: 90000000 adrp x0, 0 <runtime.firstmoduledata> + // 0: R_AARCH64_ADR_PREL_PG_HI21 local.moduledata + // 4: 91000000 add x0, x0, #0x0 + // 4: R_AARCH64_ADD_ABS_LO12_NC local.moduledata + o(0x90000000) + o(0x91000000) + rel := ld.Addrel(initfunc) + rel.Off = 0 + rel.Siz = 8 + rel.Sym = ld.Ctxt.Moduledata + rel.Type = obj.R_ADDRARM64 + + // 8: 14000000 bl 0 <runtime.addmoduledata> + // 8: R_AARCH64_CALL26 runtime.addmoduledata + o(0x14000000) + rel = ld.Addrel(initfunc) + rel.Off = 8 + rel.Siz = 4 + rel.Sym = ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0) + rel.Type = obj.R_CALLARM64 // Really should be R_AARCH64_JUMP26 but doesn't seem to make any difference + + if ld.Ctxt.Etextp != nil { + ld.Ctxt.Etextp.Next = initfunc + } else { + ld.Ctxt.Textp = initfunc + } + ld.Ctxt.Etextp = initfunc + initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0) + initarray_entry.Reachable = true + initarray_entry.Local = true + initarray_entry.Type = obj.SINITARR + ld.Addaddr(ld.Ctxt, initarray_entry, initfunc) +} func adddynrela(rel *ld.LSym, s *ld.LSym, r *ld.Reloc) { log.Fatalf("adddynrela not implemented") diff --git a/src/runtime/asm_arm64.s b/src/runtime/asm_arm64.s index 4c964c0b2d..80309868f4 100644 --- a/src/runtime/asm_arm64.s +++ b/src/runtime/asm_arm64.s @@ -1030,3 +1030,14 @@ TEXT runtime路prefetchnta(SB),NOSPLIT,$0-8 TEXT runtime路sigreturn(SB),NOSPLIT,$0-8 RET + +// This is called from .init_array and follows the platform, not Go, ABI. +TEXT runtime路addmoduledata(SB),NOSPLIT,$0-0 + SUB $0x10, RSP + MOVD R27, 8(RSP) // The access to global variables below implicitly uses R27, which is callee-save + MOVD runtime路lastmoduledatap(SB), R1 + MOVD R0, moduledata_next(R1) + MOVD R0, runtime路lastmoduledatap(SB) + MOVD 8(RSP), R27 + ADD $0x10, RSP + RET -- 2.30.9