aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/link/internal/amd64
diff options
context:
space:
mode:
authorCherry Mui <cherryyz@google.com>2023-06-08 12:19:54 -0400
committerCherry Mui <cherryyz@google.com>2023-07-20 19:39:32 +0000
commitac81156bce3ff4bfdcf983cf21acb6830a450a4b (patch)
tree2ea28191bd8b8f0311785496800a0efde2384b6f /src/cmd/link/internal/amd64
parent3ffc8a25569ed107ebc1786bbd4f993dd6689601 (diff)
downloadgo-ac81156bce3ff4bfdcf983cf21acb6830a450a4b.tar.xz
cmd/link: handle dynamic import variables on Darwin
Currently, on darwin, we only support cgo_dynamic_import for functions, but not variables, as we don't need it before. mach_task_self_ is a variable defined in the system library, which can be used to e.g. access the process's memory mappings via the mach API. The C header defines a macro mach_task_self(), which refers to the variable. To use mach_task_self_ (in pure-Go programs) we need to access it in Go. This CL handles cgo_dynamic_import for variables in the linker, loading its address via the GOT. (Currently only on Darwin, as we only need it there.) For #50891. Change-Id: Idf64fa88ba2f2381443a1ed0b42b14b581843493 Reviewed-on: https://go-review.googlesource.com/c/go/+/501855 Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com>
Diffstat (limited to 'src/cmd/link/internal/amd64')
-rw-r--r--src/cmd/link/internal/amd64/asm.go23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/cmd/link/internal/amd64/asm.go b/src/cmd/link/internal/amd64/asm.go
index c91e37584c..c4134262c5 100644
--- a/src/cmd/link/internal/amd64/asm.go
+++ b/src/cmd/link/internal/amd64/asm.go
@@ -251,6 +251,29 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade
// nothing to do, the relocation will be laid out in reloc
return true
}
+ if r.Type() == objabi.R_PCREL && ldr.SymType(s) == sym.STEXT && target.IsDarwin() {
+ // Loading the address of a dynamic symbol. Rewrite to use GOT.
+ // turn LEAQ symbol address to MOVQ of GOT entry
+ if r.Add() != 0 {
+ ldr.Errorf(s, "unexpected nonzero addend for dynamic symbol %s", ldr.SymName(targ))
+ return false
+ }
+ su := ldr.MakeSymbolUpdater(s)
+ if r.Off() >= 2 && su.Data()[r.Off()-2] == 0x8d {
+ su.MakeWritable()
+ su.Data()[r.Off()-2] = 0x8b
+ if target.IsInternal() {
+ ld.AddGotSym(target, ldr, syms, targ, 0)
+ su.SetRelocSym(rIdx, syms.GOT)
+ su.SetRelocAdd(rIdx, int64(ldr.SymGot(targ)))
+ } else {
+ su.SetRelocType(rIdx, objabi.R_GOTPCREL)
+ }
+ return true
+ }
+ ldr.Errorf(s, "unexpected R_PCREL reloc for dynamic symbol %s: not preceded by LEAQ instruction", ldr.SymName(targ))
+ return false
+ }
if target.IsExternal() {
// External linker will do this relocation.
return true