3

The other answers don't tell me how to compile, I'm stuck

I have a simple hello world in assembly

    .global start
    .align 2

    start: mov X0, #1
        adr     X1, hello
        mov     X2, #13
        mov     X16, #4
        svc     0

        mov     X0, #0
        mov     X16, #1
        svc     0

    hello: .ascii  "Hello\n"

I compiled it using clang hello.s -nostdlib -static
File says

% file ./a.out 
./a.out: Mach-O 64-bit executable arm64

obj dump shows this and perhaps UNKNOWN_ARCHITECTURE is the problem?

    ./a.out:     file format mach-o-arm64


    Disassembly of section .text:

    0000000100003fd8 <start>:
        100003fd8:  d2800020    mov x0, #0x1                    // #1
        100003fdc:  100000e1    adr x1, 100003ff8 <hello>
        100003fe0:  d28001a2    mov x2, #0xd                    // #13
        100003fe4:  d2800090    mov x16, #0x4                       // #4
        100003fe8:  d4000001    svc #0x0
        100003fec:  d2800000    mov x0, #0x0                    // #0
        100003ff0:  d2800030    mov x16, #0x1                       // #1
        100003ff4:  d4000001    svc #0x0

    0000000100003ff8 <hello>:
        100003ff8:  6c6c6548    ldnp    d8, d25, [x10, #-320]
        100003ffc:  Address 0x0000000100003ffc is out of bounds.


    Disassembly of section LC_THREAD.UNKNOWN_ARCHITECTURE.0:

    0000000000000000 <LC_THREAD.UNKNOWN_ARCHITECTURE.0>:
        ...
    100:    00003fd8    udf #16344
    104:    00000001    udf #1
        ...

Running in zsh says "killed" with error code 137.

This is what dtruss says

    % sudo dtruss ./a.out                                     
    dtrace: system integrity protection is on, some features will not be available

    dtrace: failed to execute ./a.out: Bad executable (or shared library)

Where did I go wrong? I'm on a M2

Stan
  • 161
  • 8

1 Answers1

4

The kernel on arm64 macOS does not allow static binaries. It's as simple as that, see Why does macOS kill static executables created by clang?

But you don't need your binary to be static. Just rename start to _main and compile with clang hello.s and it will work.

Siguza
  • 21,155
  • 6
  • 52
  • 89
  • I'm too new to upvote. TY for the answer. Would you happen to know how I might be able to compile this code on linux and run on my mac? I suspect clang on linux can output ARM64 and mach-o (I haven't tried yet). The part I'm clueless about is how to say link to `/usr/lib/libSystem.B.dylib` (I got that path by running `otool -L ./a.out`) – Stan Dec 02 '22 at 18:38
  • @Stan cross-compiling for Darwin targets is not pretty. Clang is multi-target by default, so you start with `--target=arm64-apple-macos`, but then you need the SDK. You can rip that out of Xcode (`find /Applications/Xcode.app -name MacOSX.sdk`) or the Xcode CLI tools and pass it to clang with `--sysroot=...`. And I'm not sure what the linker defaults are, so you should add `-fuse-ld=ld64.lld` (which you might have to install separately). If that works, great. But it might fail for two common reasons: 1) lld doesn't support even the most basic of options or 2) you don't have libclang_rt. – Siguza Dec 02 '22 at 19:07
  • I seem to figured out how to build the assembly on linux and use a mach-o linker. Now it looks like I need to set the dylib path -edit- You commented when I did – Stan Dec 02 '22 at 19:08
  • In case 1), refer to [this repo](https://github.com/tpoechtrager/cctools-port) to build Apple's `ld64` and use it with `-fuse-ld=path/to/ld64`. In case 2), download a build of clang+LLVM for Darwin targets, rip the folders with libclang_rt out of them and pass them to clang with `-resource-dir=...` (such that `.../lib/darwin/` has the `.a` files in it). – Siguza Dec 02 '22 at 19:09
  • I moved onto how to compile it from linux to mac https://stackoverflow.com/questions/74660777/how-to-cross-compile-arm64-assembly-from-linux-to-mac – Stan Dec 02 '22 at 20:30