]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: add windows/arm64 support
authorRuss Cox <rsc@golang.org>
Wed, 27 Jan 2021 17:35:16 +0000 (12:35 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 19 Feb 2021 00:40:16 +0000 (00:40 +0000)
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>
src/cmd/link/internal/arm64/asm.go
src/cmd/link/internal/arm64/obj.go
src/cmd/link/internal/ld/config.go
src/cmd/link/internal/ld/pe.go

index 14a20a17d53a49229583ec46a0849deff70215d5..72093268c220a6bd75476863849755b41d0f0d40 100644 (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
index bd13295e6130bee64c6d7c44e3dfe0400c95d283..18a32531e9035ff00f52e5d0eb4bd70af2ea17c2 100644 (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
        }
 }
index d1e06239a566f656ed67e69597b99bd4c790122e..481dc6747501db2aedf38689a97932913ea9d14d 100644 (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.
index c46036c7eaa4386b1f1edf0e6235d83e8cce9dae..36c8e0da9a7d62f8af18201ee9b7809193da2d22 100644 (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))