mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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:
parent
95a44d2409
commit
985d087782
4 changed files with 69 additions and 4 deletions
|
|
@ -568,6 +568,40 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
|
||||||
return true
|
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) {
|
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 noExtReloc = 0
|
||||||
const isOk = true
|
const isOk = true
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||||
GenSymsLate: gensymlate,
|
GenSymsLate: gensymlate,
|
||||||
Machoreloc1: machoreloc1,
|
Machoreloc1: machoreloc1,
|
||||||
MachorelocSize: 8,
|
MachorelocSize: 8,
|
||||||
|
PEreloc1: pereloc1,
|
||||||
|
|
||||||
Androiddynld: "/system/bin/linker64",
|
Androiddynld: "/system/bin/linker64",
|
||||||
Linuxdynld: "/lib/ld-linux-aarch64.so.1",
|
Linuxdynld: "/lib/ld-linux-aarch64.so.1",
|
||||||
|
|
@ -108,5 +109,9 @@ func archinit(ctxt *ld.Link) {
|
||||||
if *ld.FlagRound == -1 {
|
if *ld.FlagRound == -1 {
|
||||||
*ld.FlagRound = 16384 // 16K page alignment
|
*ld.FlagRound = 16384 // 16K page alignment
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case objabi.Hwindows: /* PE executable */
|
||||||
|
// ld.HEADR, ld.FlagTextAddr, ld.FlagRound are set in ld.Peinit
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ func (mode *BuildMode) Set(s string) error {
|
||||||
return fmt.Errorf("invalid buildmode: %q", s)
|
return fmt.Errorf("invalid buildmode: %q", s)
|
||||||
case "exe":
|
case "exe":
|
||||||
switch objabi.GOOS + "/" + objabi.GOARCH {
|
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
|
*mode = BuildModePIE
|
||||||
default:
|
default:
|
||||||
*mode = BuildModeExe
|
*mode = BuildModeExe
|
||||||
|
|
@ -65,7 +65,7 @@ func (mode *BuildMode) Set(s string) error {
|
||||||
}
|
}
|
||||||
case "windows":
|
case "windows":
|
||||||
switch objabi.GOARCH {
|
switch objabi.GOARCH {
|
||||||
case "amd64", "386", "arm":
|
case "amd64", "386", "arm", "arm64":
|
||||||
default:
|
default:
|
||||||
return badmode()
|
return badmode()
|
||||||
}
|
}
|
||||||
|
|
@ -220,7 +220,7 @@ func mustLinkExternal(ctxt *Link) (res bool, reason string) {
|
||||||
case BuildModePIE:
|
case BuildModePIE:
|
||||||
switch objabi.GOOS + "/" + objabi.GOARCH {
|
switch objabi.GOOS + "/" + objabi.GOARCH {
|
||||||
case "linux/amd64", "linux/arm64", "android/arm64":
|
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":
|
case "darwin/amd64", "darwin/arm64":
|
||||||
default:
|
default:
|
||||||
// Internal linking does not support TLS_IE.
|
// Internal linking does not support TLS_IE.
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ const (
|
||||||
IMAGE_SCN_ALIGN_32BYTES = 0x600000
|
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.
|
// TODO(crawshaw): add these constants to debug/pe.
|
||||||
const (
|
const (
|
||||||
// TODO: the Microsoft doco says IMAGE_SYM_DTYPE_ARRAY is 3 and IMAGE_SYM_DTYPE_FUNCTION is 2
|
// 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_BRANCH11 = 0x0004
|
||||||
IMAGE_REL_ARM_SECREL = 0x000F
|
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_HIGHLOW = 3
|
||||||
IMAGE_REL_BASED_DIR64 = 10
|
IMAGE_REL_BASED_DIR64 = 10
|
||||||
)
|
)
|
||||||
|
|
@ -465,6 +485,8 @@ func (f *peFile) addInitArray(ctxt *Link) *peSection {
|
||||||
size = 8
|
size = 8
|
||||||
case "arm":
|
case "arm":
|
||||||
size = 4
|
size = 4
|
||||||
|
case "arm64":
|
||||||
|
size = 8
|
||||||
}
|
}
|
||||||
sect := f.addSection(".ctors", size, size)
|
sect := f.addSection(".ctors", size, size)
|
||||||
sect.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
|
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 {
|
switch objabi.GOARCH {
|
||||||
case "386", "arm":
|
case "386", "arm":
|
||||||
ctxt.Out.Write32(uint32(addr))
|
ctxt.Out.Write32(uint32(addr))
|
||||||
case "amd64":
|
case "amd64", "arm64":
|
||||||
ctxt.Out.Write64(addr)
|
ctxt.Out.Write64(addr)
|
||||||
}
|
}
|
||||||
return sect
|
return sect
|
||||||
|
|
@ -594,6 +616,8 @@ dwarfLoop:
|
||||||
ctxt.Out.Write16(IMAGE_REL_AMD64_ADDR64)
|
ctxt.Out.Write16(IMAGE_REL_AMD64_ADDR64)
|
||||||
case "arm":
|
case "arm":
|
||||||
ctxt.Out.Write16(IMAGE_REL_ARM_ADDR32)
|
ctxt.Out.Write16(IMAGE_REL_ARM_ADDR32)
|
||||||
|
case "arm64":
|
||||||
|
ctxt.Out.Write16(IMAGE_REL_ARM64_ADDR64)
|
||||||
}
|
}
|
||||||
return 1
|
return 1
|
||||||
})
|
})
|
||||||
|
|
@ -788,6 +812,8 @@ func (f *peFile) writeFileHeader(ctxt *Link) {
|
||||||
fh.Machine = pe.IMAGE_FILE_MACHINE_I386
|
fh.Machine = pe.IMAGE_FILE_MACHINE_I386
|
||||||
case sys.ARM:
|
case sys.ARM:
|
||||||
fh.Machine = pe.IMAGE_FILE_MACHINE_ARMNT
|
fh.Machine = pe.IMAGE_FILE_MACHINE_ARMNT
|
||||||
|
case sys.ARM64:
|
||||||
|
fh.Machine = pe.IMAGE_FILE_MACHINE_ARM64
|
||||||
}
|
}
|
||||||
|
|
||||||
fh.NumberOfSections = uint16(len(f.sections))
|
fh.NumberOfSections = uint16(len(f.sections))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue