Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: cmd/compile, cmd/cgo: support targeting arm64_32 #60180

Closed
sandler31 opened this issue May 14, 2023 · 5 comments
Closed

proposal: cmd/compile, cmd/cgo: support targeting arm64_32 #60180

sandler31 opened this issue May 14, 2023 · 5 comments
Labels
Milestone

Comments

@sandler31
Copy link

I've tried to compile a go module using the "c-archive" mode in order to include in an Xcode project, targeted for the WatchOS (running on the Apple Watch).

After performing all the necessary steps to do so, I've discovered that it's not currently possible, due to the fact that the WatchOS is expecting binaries to target the special "ARM64_32" CPU type, which according to them means "64-bit hardware with 32-bit types".

I used the following script in my go module compilation attempt:

#!/bin/sh -eu

export CGO_ENABLED=1
export GOOS=ios
export GOARCH=arm64
export SDK=watchos
export CGO_CFLAGS="-fembed-bitcode"

go build -buildmode=c-archive -trimpath -o out.a ./

With the following code:

package main

import "C"

//export foo
func foo() *C.char {
	return C.CString("bar")
}

func main() {}

Of course, as I already said, this produces the expected binary as per the GOOS/GOARCH values, but not the one needed to run on WatchOS:

otool -h out.a                  
Archive : out.a
out.a(go.o):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           1     4       1880 0x00000000
out.a(000000.o):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           1     4        600 0x00002000
out.a(000001.o):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           1     4        440 0x00002000
out.a(000002.o):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           1     4        440 0x00002000
out.a(000003.o):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           1     4        440 0x00002000
out.a(000004.o):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           1     4        520 0x00002000
out.a(000005.o):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           1     4        680 0x00002000
out.a(000006.o):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           1     4        760 0x00002000
out.a(000007.o):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           1     4        520 0x00002000
out.a(000008.o):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           1     4        520 0x00002000
out.a(000009.o):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           1     4        520 0x00002000
out.a(000010.o):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           1     4        680 0x00002000
out.a(000011.o):
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           1     4        520 0x00000000

16777228 being (CPU_TYPE_ARM | CPU_ARCH_ABI64)

The correct binary format can be achieved by compiling a simple c file, targeting the correct CPU type:

#!/bin/sh -eu

SDK=watchos
SDK_PATH=`xcrun --sdk $SDK --show-sdk-path`
CLANG=`xcrun --sdk $SDK --find clang`
CARCH=arm64_32
$CLANG -arch $CARCH -isysroot $SDK_PATH -mwatchos-version-min=9.0 -c main.c -o c_out.a
int foo (int a) {
    return a;
}

Which results with the following:

otool -h c_out.a 
c_out.a:
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedface 33554444          1  0x00           1     4        320 0x00002000

33554444 being (CPU_TYPE_ARM | CPU_ARCH_ABI64_32), and CPU sutype CPU_SUBTYPE_ARM64_V8

I realize this might require some serious work to be supported, and would be happy to try and work on this myself, unfortunately this is not really my area of expertise, and I have very minimal knowledge of the golang/cgo compilation internals.
If there is no possibility this would be supported in the foreseeable future, I would be happy to receive some pointers on the areas where said work needs to be done.

On a side note, when researching this topic, I found out that support for targeting this architecture has been implemented in llvm (https://reviews.llvm.org/D99822), but seeing as gollvm does not even seem to support compiling to darwin, this seems like a dead end.

@gopherbot gopherbot added this to the Proposal milestone May 14, 2023
@seankhliao seankhliao changed the title proposal: compile, cgo: support targeting arm64_32 proposal: cmd/compile, cmd/cgo: support targeting arm64_32 May 14, 2023
@ianlancetaylor
Copy link
Contributor

CC @golang/runtime

@rsc
Copy link
Contributor

rsc commented Dec 4, 2023

We used to have a Native Client port that was basically x86 in a 64-bit address space with 32-bit pointers. It was a unique snowflake that broke all kinds of assumptions in the runtime and frequently broke, and I was very happy to see it removed. As a matter of policy I don't think the Go project wants to commit to another mixed-size architecture, especially just for one commercial product (the Apple Watch).

If you wanted to work on an adaptation, the Go side could probably still use 64-bit data types, but then probably the main place that needs changes is where packages runtime and syscall call into macOS (or watchOS) shared libraries. Those will need to adjust the arguments appropriately. But we are unlikely to accept that port back into the main tree.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2023

This proposal has been added to the active column of the proposals project
and will now be reviewed at the weekly proposal review meetings.
— rsc for the proposal review group

@rsc
Copy link
Contributor

rsc commented Dec 9, 2023

Based on the discussion above, this proposal seems like a likely decline.
— rsc for the proposal review group

@rsc
Copy link
Contributor

rsc commented Dec 14, 2023

No change in consensus, so declined.
— rsc for the proposal review group

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Declined
Development

No branches or pull requests

4 participants