cmd/link: add windows/arm64 support

This CL is part of a stack adding windows/arm64
support (#36439), intended to land in the Go 1.17 cycle.

Change-Id: I397c1d238bb18cbe78b3fca00910660cf1d66b8d
Reviewed-on: https://go-review.googlesource.com/c/go/+/288822
Trust: Russ Cox <rsc@golang.org>
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Russ Cox 2021-01-27 12:35:16 -05:00
parent 95a44d2409
commit 985d087782
4 changed files with 69 additions and 4 deletions

View file

@ -568,6 +568,40 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
return true
}
func pereloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
rt := r.Type
if ldr.SymDynid(rs) < 0 {
ldr.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs))
return false
}
out.Write32(uint32(sectoff))
out.Write32(uint32(ldr.SymDynid(rs)))
switch rt {
default:
return false
case objabi.R_DWARFSECREF:
v = ld.IMAGE_REL_ARM64_SECREL
case objabi.R_ADDR:
if r.Size == 8 {
v = ld.IMAGE_REL_ARM64_ADDR64
} else {
v = ld.IMAGE_REL_ARM64_ADDR32
}
}
out.Write16(uint16(v))
return true
}
func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc, s loader.Sym, val int64) (int64, int, bool) {
const noExtReloc = 0
const isOk = true

View file

@ -58,6 +58,7 @@ func Init() (*sys.Arch, ld.Arch) {
GenSymsLate: gensymlate,
Machoreloc1: machoreloc1,
MachorelocSize: 8,
PEreloc1: pereloc1,
Androiddynld: "/system/bin/linker64",
Linuxdynld: "/lib/ld-linux-aarch64.so.1",
@ -108,5 +109,9 @@ func archinit(ctxt *ld.Link) {
if *ld.FlagRound == -1 {
*ld.FlagRound = 16384 // 16K page alignment
}
case objabi.Hwindows: /* PE executable */
// ld.HEADR, ld.FlagTextAddr, ld.FlagRound are set in ld.Peinit
return
}
}

View file

@ -36,7 +36,7 @@ func (mode *BuildMode) Set(s string) error {
return fmt.Errorf("invalid buildmode: %q", s)
case "exe":
switch objabi.GOOS + "/" + objabi.GOARCH {
case "darwin/arm64", "windows/arm": // On these platforms, everything is PIE
case "darwin/arm64", "windows/arm", "windows/arm64": // On these platforms, everything is PIE
*mode = BuildModePIE
default:
*mode = BuildModeExe
@ -65,7 +65,7 @@ func (mode *BuildMode) Set(s string) error {
}
case "windows":
switch objabi.GOARCH {
case "amd64", "386", "arm":
case "amd64", "386", "arm", "arm64":
default:
return badmode()
}
@ -220,7 +220,7 @@ func mustLinkExternal(ctxt *Link) (res bool, reason string) {
case BuildModePIE:
switch objabi.GOOS + "/" + objabi.GOARCH {
case "linux/amd64", "linux/arm64", "android/arm64":
case "windows/386", "windows/amd64", "windows/arm":
case "windows/386", "windows/amd64", "windows/arm", "windows/arm64":
case "darwin/amd64", "darwin/arm64":
default:
// Internal linking does not support TLS_IE.

View file

@ -69,6 +69,7 @@ const (
IMAGE_SCN_ALIGN_32BYTES = 0x600000
)
// See https://docs.microsoft.com/en-us/windows/win32/debug/pe-format.
// TODO(crawshaw): add these constants to debug/pe.
const (
// TODO: the Microsoft doco says IMAGE_SYM_DTYPE_ARRAY is 3 and IMAGE_SYM_DTYPE_FUNCTION is 2
@ -95,6 +96,25 @@ const (
IMAGE_REL_ARM_BRANCH11 = 0x0004
IMAGE_REL_ARM_SECREL = 0x000F
IMAGE_REL_ARM64_ABSOLUTE = 0x0000
IMAGE_REL_ARM64_ADDR32 = 0x0001
IMAGE_REL_ARM64_ADDR32NB = 0x0002
IMAGE_REL_ARM64_BRANCH26 = 0x0003
IMAGE_REL_ARM64_PAGEBASE_REL21 = 0x0004
IMAGE_REL_ARM64_REL21 = 0x0005
IMAGE_REL_ARM64_PAGEOFFSET_12A = 0x0006
IMAGE_REL_ARM64_PAGEOFFSET_12L = 0x0007
IMAGE_REL_ARM64_SECREL = 0x0008
IMAGE_REL_ARM64_SECREL_LOW12A = 0x0009
IMAGE_REL_ARM64_SECREL_HIGH12A = 0x000A
IMAGE_REL_ARM64_SECREL_LOW12L = 0x000B
IMAGE_REL_ARM64_TOKEN = 0x000C
IMAGE_REL_ARM64_SECTION = 0x000D
IMAGE_REL_ARM64_ADDR64 = 0x000E
IMAGE_REL_ARM64_BRANCH19 = 0x000F
IMAGE_REL_ARM64_BRANCH14 = 0x0010
IMAGE_REL_ARM64_REL32 = 0x0011
IMAGE_REL_BASED_HIGHLOW = 3
IMAGE_REL_BASED_DIR64 = 10
)
@ -465,6 +485,8 @@ func (f *peFile) addInitArray(ctxt *Link) *peSection {
size = 8
case "arm":
size = 4
case "arm64":
size = 8
}
sect := f.addSection(".ctors", size, size)
sect.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
@ -477,7 +499,7 @@ func (f *peFile) addInitArray(ctxt *Link) *peSection {
switch objabi.GOARCH {
case "386", "arm":
ctxt.Out.Write32(uint32(addr))
case "amd64":
case "amd64", "arm64":
ctxt.Out.Write64(addr)
}
return sect
@ -594,6 +616,8 @@ dwarfLoop:
ctxt.Out.Write16(IMAGE_REL_AMD64_ADDR64)
case "arm":
ctxt.Out.Write16(IMAGE_REL_ARM_ADDR32)
case "arm64":
ctxt.Out.Write16(IMAGE_REL_ARM64_ADDR64)
}
return 1
})
@ -788,6 +812,8 @@ func (f *peFile) writeFileHeader(ctxt *Link) {
fh.Machine = pe.IMAGE_FILE_MACHINE_I386
case sys.ARM:
fh.Machine = pe.IMAGE_FILE_MACHINE_ARMNT
case sys.ARM64:
fh.Machine = pe.IMAGE_FILE_MACHINE_ARM64
}
fh.NumberOfSections = uint16(len(f.sections))