Commit 1b4d28f8 authored by Michael Hudson-Doyle's avatar Michael Hudson-Doyle

cmd/link, runtime: arm implementation of addmoduledata

Change-Id: I3975e10c2445e23c2798a7203a877ff2de3427c7
Reviewed-on: https://go-review.googlesource.com/14189Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent 3953c1d8
......@@ -37,7 +37,75 @@ import (
"log"
)
// This assembler:
//
// .align 2
// local.dso_init:
// ldr r0, .Lmoduledata
// .Lloadfrom:
// ldr r0, [r0]
// b runtime.addmoduledata@plt
// .align 2
// .Lmoduledata:
// .word local.moduledata(GOT_PREL) + (. - (.Lloadfrom + 4))
// assembles to:
//
// 00000000 <local.dso_init>:
// 0: e59f0004 ldr r0, [pc, #4] ; c <local.dso_init+0xc>
// 4: e5900000 ldr r0, [r0]
// 8: eafffffe b 0 <runtime.addmoduledata>
// 8: R_ARM_JUMP24 runtime.addmoduledata
// c: 00000004 .word 0x00000004
// c: R_ARM_GOT_PREL local.moduledata
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)
}
o(0xe59f0004)
o(0xe08f0000)
o(0xeafffffe)
rel := ld.Addrel(initfunc)
rel.Off = 8
rel.Siz = 4
rel.Sym = ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0)
rel.Type = obj.R_CALLARM
rel.Add = 0xeafffffe // vomit
o(0x00000000)
rel = ld.Addrel(initfunc)
rel.Off = 12
rel.Siz = 4
rel.Sym = ld.Ctxt.Moduledata
rel.Type = obj.R_PCREL
rel.Add = 4
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)
}
// Preserve highest 8 bits of a, and do addition to lower 24-bit
......@@ -228,6 +296,13 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
case obj.R_TLS_IE:
ld.Thearch.Lput(ld.R_ARM_TLS_IE32 | uint32(elfsym)<<8)
case obj.R_GOTPCREL:
if r.Siz == 4 {
ld.Thearch.Lput(ld.R_ARM_GOT_PREL | uint32(elfsym)<<8)
} else {
return -1
}
}
return 0
......
......@@ -1076,3 +1076,14 @@ TEXT runtime·usplitR0(SB),NOSPLIT,$0
TEXT runtime·sigreturn(SB),NOSPLIT,$0-4
RET
#ifndef GOOS_nacl
// This is called from .init_array and follows the platform, not Go, ABI.
TEXT runtime·addmoduledata(SB),NOSPLIT,$0-4
MOVW R9, saver9-4(SP) // The access to global variables below implicitly uses R9, which is callee-save
MOVW runtime·lastmoduledatap(SB), R1
MOVW R0, moduledata_next(R1)
MOVW R0, runtime·lastmoduledatap(SB)
MOVW saver9-4(SP), R9
RET
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment