]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link/internal/ld: enable bitcode builds for iOS, tvOS, watchOS
authorElias Naur <mail@eliasnaur.com>
Sun, 17 Mar 2019 16:48:57 +0000 (17:48 +0100)
committerElias Naur <mail@eliasnaur.com>
Thu, 21 Mar 2019 01:34:26 +0000 (01:34 +0000)
The Go toolchain cannot output bitcode, but there is a trick where
object code can be marked with an __asm section, persuading the
Apple toolchain to include our object code in bitcode builds.

This enables Go builds with bitcode enabled; the next CL adds
the necessary plumbing for building on tvOS and watchOS.

Thanks to Aman Gupta for the trick.

Test is added two CLs from here.

Fixes #22395 (at least until Apple tightens bitcode requirements.)

Change-Id: Ic1c1448c4d46222bb3dd097b1f4df80848051e5f
Reviewed-on: https://go-review.googlesource.com/c/go/+/168320
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/link/internal/ld/macho.go

index b935814ff0a432a4232186139f646e7cd6e8ff77..f2756678d6756b5f2df6080da1fe0c51f72b73a7 100644 (file)
@@ -395,6 +395,14 @@ func (ctxt *Link) domacho() {
                s.Type = sym.SMACHOINDIRECTGOT
                s.Attr |= sym.AttrReachable
        }
+
+       // Add a dummy symbol that will become the __asm marker section.
+       if ctxt.LinkMode == LinkExternal {
+               s := ctxt.Syms.Lookup(".llvmasm", 0)
+               s.Type = sym.SMACHO
+               s.Attr |= sym.AttrReachable
+               s.AddUint8(0)
+       }
 }
 
 func machoadddynlib(lib string, linkmode LinkMode) {
@@ -481,6 +489,17 @@ func machoshbits(ctxt *Link, mseg *MachoSeg, sect *sym.Section, segname string)
                msect.flag = S_MOD_INIT_FUNC_POINTERS
        }
 
+       // Some platforms such as watchOS and tvOS require binaries with
+       // bitcode enabled. The Go toolchain can't output bitcode, so use
+       // a marker section in the __LLVM segment, "__asm", to tell the Apple
+       // toolchain that the Go text came from assembler and thus has no
+       // bitcode. This is not true, but Kotlin/Native, Rust and Flutter
+       // are also using this trick.
+       if sect.Name == ".llvmasm" {
+               msect.name = "__asm"
+               msect.segname = "__LLVM"
+       }
+
        if segname == "__DWARF" {
                msect.flag |= S_ATTR_DEBUG
        }