diff options
| author | Cherry Mui <cherryyz@google.com> | 2023-06-08 12:19:54 -0400 |
|---|---|---|
| committer | Cherry Mui <cherryyz@google.com> | 2023-07-20 19:39:32 +0000 |
| commit | ac81156bce3ff4bfdcf983cf21acb6830a450a4b (patch) | |
| tree | 2ea28191bd8b8f0311785496800a0efde2384b6f /src/cmd/link/internal/amd64 | |
| parent | 3ffc8a25569ed107ebc1786bbd4f993dd6689601 (diff) | |
| download | go-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.go | 23 |
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 |
