title: Why does my native arm64 application built using an x86_64 build system fail to be code signed unless I remove the previous executable?
body: <p>I have a simple C application:</p>
  <pre class="lang-c prettyprint-override"><code>#include &lt;stdio.h&gt;
  
  int main() {
    printf(&quot;Hello, world!\n&quot;);
  }
  </code></pre>
  <p>When I:</p>
  <ol>
  <li>build this on an Apple Silicon device</li>
  <li>targeting arm64</li>
  <li>using a build system that is compiled for x86_64</li>
  <li>replace an existing binary (such as during a rebuild)</li>
  </ol>
  <p>The final binary cannot be executed and is reported as &quot;killed&quot; according to the shell:</p>
  <pre class="lang-none prettyprint-override"><code>% rm hello
  
  # arch simulates the build system which is still compiled for x86_64
  % arch -x86_64 cc -arch arm64 hello.c -o hello
  
  % ./hello
  Hello, world!
  
  % arch -x86_64 cc -arch arm64 hello.c -o hello
  
  % ./hello
  zsh: killed     ./hello
  </code></pre>
  <p>If my build system is native arm64 (or arm64e), then there's no problem:</p>
  <pre class="lang-none prettyprint-override"><code>% rm hello
  
  % arch -arm64e cc -arch arm64 hello.c -o hello
  
  % ./hello
  Hello, world!
  
  % arch -arm64e cc -arch arm64 hello.c -o hello
  
  % ./hello
  Hello, world!
  </code></pre>
  <p>If I <a href="https://github.com/Homebrew/brew/issues/9082#issuecomment-727246564" rel="noreferrer"><strong>copy</strong> the binary to a new path</a> and then replace the code signature, then it works:</p>
  <pre class="lang-none prettyprint-override"><code>% cp hello hello2
  
  % codesign -s - -f hello2
  hello2: replacing existing signature
  
  % ./hello2
  Hello, world!
  </code></pre>
  <hr />
  <h1>Original reproduction steps and debugging</h1>
  <p>When I build this on an Apple Silicon device, targeting arm64, but using a build system that is compiled for x86_64, the final binary cannot be executed and is reported as &quot;killed&quot; according to the shell:</p>
  <pre class="lang-none prettyprint-override"><code># arch simulates the build system which is still compiled for x86_64
  % arch -x86_64 cc -arch arm64 hello.c -o hello
  
  % file hello
  hello: Mach-O 64-bit executable arm64
  
  % ./hello
  zsh: killed     ./hello
  </code></pre>
  <p>Even attempting to debug it fails:</p>
  <pre class="lang-none prettyprint-override"><code>% lldb hello
  (lldb) target create &quot;hello&quot;
  zsh: killed     lldb hello
  </code></pre>
  <p>As a workaround, I can <a href="https://stackoverflow.com/q/64830635/155423">use a shim compiler</a> to &quot;reset&quot; back to an arm64 environment before calling <code>cc</code>, but that's inelegant and it feels like I'm missing some configuration to avoid jumping through so many hoops.</p>
  <pre class="lang-none prettyprint-override"><code>% cc --version
  Apple clang version 12.0.0 (clang-1200.0.32.27)
  Target: arm64-apple-darwin20.1.0
  Thread model: posix
  InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
  </code></pre>
  <p>This is on macOS Big Sur 11.0.1.</p>
  <h2>Cross compiling from x86_64</h2>
  <p>If I cross-compile from an x86_64 machine and scp the binary around, the file executes fine:</p>
  <pre class="lang-none prettyprint-override"><code>% SDKROOT=$(xcrun -sdk macosx11.0 --show-sdk-path) \
  MACOSX_DEPLOYMENT_TARGET=$(xcrun -sdk macosx11.0 --show-sdk-platform-version) \
  cc -arch arm64 hello.c -o hello
  
  % scp hello silicon:/tmp/hello-cross
  </code></pre>
  <p>Switch machines...</p>
  <pre class="lang-none prettyprint-override"><code>% file /tmp/hello-cross
  /tmp/hello-cross: Mach-O 64-bit executable arm64
  
  % /tmp/hello-cross
  Hello, world!
  </code></pre>
  <h2>Tracing child processes</h2>
  <p>Adding <code>--verbose</code> to the <code>cc</code> invocation prints out the child processes (I added newlines to highlight those among the other debugging):</p>
  <pre class="lang-none prettyprint-override"><code>% arch -x86_64 cc --verbose -arch arm64 hello.c -o hello
  Apple clang version 12.0.0 (clang-1200.0.32.27)
  Target: aarch64-apple-darwin20.1.0
  Thread model: posix
  InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
  
   &quot;/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang&quot; -cc1 -triple arm64-apple-macosx11.0.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -Werror=implicit-function-declaration -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name hello.c -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=non-leaf -fno-strict-return -masm-verbose -munwind-tables -target-sdk-version=11.0 -target-cpu vortex -target-feature +v8.3a -target-feature +fp-armv8 -target-feature +neon -target-feature +crc -target-feature +crypto -target-feature +fullfp16 -target-feature +ras -target-feature +lse -target-feature +rdm -target-feature +rcpc -target-feature +zcm -target-feature +zcz -target-feature +sha2 -target-feature +aes -target-abi darwinpcs -fallow-half-arguments-and-returns -dwarf-column-info -debugger-tuning=lldb -target-linker-version 609.6 -v -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -I/usr/local/include -internal-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/local/include -internal-isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.0/include -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -Wno-reorder-init-list -Wno-implicit-int-float-conversion -Wno-c99-designator -Wno-final-dtor-non-final-class -Wno-extra-semi-stmt -Wno-misleading-indentation -Wno-quoted-include-in-framework-header -Wno-implicit-fallthrough -Wno-enum-enum-conversion -Wno-enum-float-conversion -fdebug-compilation-dir /tmp/example -ferror-limit 19 -fmessage-length 237 -stack-protector 1 -fstack-check -mdarwin-stkchk-strong-link -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fobjc-runtime=macosx-11.0.0 -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -o /var/folders/j2/g4_hr3jd2sz415vrf7b1d6300000gp/T/hello-232f6b.o -x c hello.c
  
  clang -cc1 version 12.0.0 (clang-1200.0.32.27) default target x86_64-apple-darwin20.1.0
  ignoring nonexistent directory &quot;/usr/local/include&quot;
  ignoring nonexistent directory &quot;/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/local/include&quot;
  ignoring nonexistent directory &quot;/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks&quot;
  #include &quot;...&quot; search starts here:
  #include &lt;...&gt; search starts here:
   /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.0/include
   /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include
   /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
   /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory)
  End of search list.
  
   &quot;/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld&quot; -demangle -lto_library /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libLTO.dylib -no_deduplicate -dynamic -arch arm64 -platform_version macos 11.0.0 11.0 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -o hello -L/usr/local/lib /var/folders/j2/g4_hr3jd2sz415vrf7b1d6300000gp/T/hello-232f6b.o -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.0/lib/darwin/libclang_rt.osx.a
  </code></pre>
  <p>The compiler invocation has <code>-triple arm64-apple-macosx11.0.0</code> and the linker invocation has <code>-arch arm64</code>, so it seems like appropriate values are being passed.</p>
  <h2>Comparing failing and successful binaries</h2>
  <p>As suggested in a comment, I've tried comparing the two binary files. Unfortunately, the suggested <a href="https://www.scootersoftware.com/" rel="noreferrer">Beyond Compare</a> tool <em>also</em> crashes as soon as the failing executable is opened. I suspect that it's for the same underlying reason that LLDB reports being killed.</p>
  <p>In the meantime, here's the output of comparing the raw hex data:</p>
  <pre class="lang-none prettyprint-override"><code>--- /tmp/hello-cross.hex        2020-11-14 05:07:04.000000000 -0800
  +++ ./hello.hex 2020-11-14 05:06:52.000000000 -0800
  @@ -74,10 +74,10 @@
   00000490: 0000 0000 0000 0000 0000 0000 0000 0000  ................
   000004a0: 0e00 0000 2000 0000 0c00 0000 2f75 7372  .... ......./usr
   000004b0: 2f6c 6962 2f64 796c 6400 0000 0000 0000  /lib/dyld.......
  -000004c0: 1b00 0000 1800 0000 7b34 532d f414 3f99  ........{4S-..?.
  -000004d0: a866 f4d8 29bf f7ce 3200 0000 2000 0000  .f..)...2... ...
  +000004c0: 1b00 0000 1800 0000 0ad8 b6d9 c6c4 32f0  ..............2.
  +000004d0: 9522 80e2 f036 54f7 3200 0000 2000 0000  .&quot;...6T.2... ...
   000004e0: 0100 0000 0000 0b00 0000 0b00 0100 0000  ................
  -000004f0: 0300 0000 0006 6102 2a00 0000 1000 0000  ......a.*.......
  +000004f0: 0300 0000 0007 6102 2a00 0000 1000 0000  ......a.*.......
   00000500: 0000 0000 0000 0000 2800 0080 1800 0000  ........(.......
   00000510: 543f 0000 0000 0000 0000 0000 0000 0000  T?..............
   00000520: 0c00 0000 3800 0000 1800 0000 0200 0000  ....8...........
  @@ -3094,9 +3094,9 @@
   0000c150: 0000 0000 0000 0000 0000 0000 0000 0000  ................
   0000c160: 0000 0000 0000 0000 0000 0000 0000 0000  ................
   0000c170: 0000 4000 0000 0000 0000 0001 6865 6c6c  ..@.........hell
  -0000c180: 6f00 e40f cd6f 1abe f672 0c10 0915 8b30  o....o...r.....0
  -0000c190: 5c9a 4a69 c9eb efdd a655 11c8 f5dc 3d86  \.Ji.....U....=.
  -0000c1a0: b3d5 ad7f acb2 586f c6e9 66c0 04d7 d1d1  ......Xo..f.....
  +0000c180: 6f00 29f3 685d 60bf c358 4179 1735 b8b0  o.).h]`..XAy.5..
  +0000c190: d018 3ec5 aa3c 0f60 cc8b a4f2 23bf b37d  ..&gt;..&lt;.`....#..}
  +0000c1a0: 9ee8 ad7f acb2 586f c6e9 66c0 04d7 d1d1  ......Xo..f.....
   0000c1b0: 6b02 4f58 05ff 7cb4 7c7a 85da bd8b 4889  k.OX..|.|z....H.
   0000c1c0: 2ca7 ad7f acb2 586f c6e9 66c0 04d7 d1d1  ,.....Xo..f.....
   0000c1d0: 6b02 4f58 05ff 7cb4 7c7a 85da bd8b 4889  k.OX..|.|z....H.
  </code></pre>
  <p>Running <code>otool -fahlLDtvV</code> on both files and comparing the outputs yields:</p>
  <pre class="lang-none prettyprint-override"><code>--- /tmp/hello-cross.dump       2020-11-14 05:41:10.000000000 -0800
  +++ hello.dump  2020-11-14 05:41:22.000000000 -0800
  @@ -226,7 +226,7 @@
   Load command 9
        cmd LC_UUID
    cmdsize 24
  -    uuid 7B34532D-F414-3F99-A866-F4D829BFF7CE
  +    uuid 0AD8B6D9-C6C4-32F0-9522-80E2F03654F7
   Load command 10
          cmd LC_BUILD_VERSION
      cmdsize 32
  @@ -235,7 +235,7 @@
        minos 11.0
       ntools 1
         tool ld
  -   version 609.6
  +   version 609.7
   Load command 11
         cmd LC_SOURCE_VERSION
     cmdsize 16
  </code></pre>
  <p>This seems to correspond to the first hunk of the raw hex dump, suggesting that the important difference is in the second hunk.</p>
  <h2>Code signing</h2>
  <p><a href="https://sourceforge.net/projects/machoview/" rel="noreferrer">MachOView</a> indicates that address <code>0xc180</code> occurs within the &quot;Code Signature&quot; section. However, it appears that the signature is valid enough:</p>
  <pre class="lang-none prettyprint-override"><code>% codesign --verify --verbose hello
  hello: valid on disk
  hello: satisfies its Designated Requirement
  </code></pre>
  <p>Looking at Console.app, I do see these lines:</p>
  <pre class="lang-none prettyprint-override"><code>CODE SIGNING: cs_invalid_page(0x10439c000): p=32470[hello] final status 0x23020200, denying page sending SIGKILL
  CODE SIGNING: process 32470[hello]: rejecting invalid page at address 0x10439c000 from offset 0x0 in file &quot;/private/tmp/example/hello&quot; (cs_mtime:1605366572.426749233 == mtime:1605366572.426749233) (signed:1 validated:1 tainted:1 nx:0 wpmapped:1 dirty:0 depth:0)
  </code></pre>