Home > Software engineering >  Cross assemble Linux Arm64 using MacOS clang assembler
Cross assemble Linux Arm64 using MacOS clang assembler

Time:12-10

I am trying to write Assembly on MacOS using the default clang assembler.

I got this small "Hello World" working for MacOS on the same machine:

.global _main
.align 2

_main: 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 World!\n"

It is taken from this question.

When I assembler it with:

clang hello.s

I can successfully run it with:

./a.out

Now, I try to follow the "Hello World" for Linux from the book Programming with 64-Bit ARM Assembly Language. It is basically the same program, but the sys-calls is for Linux:

.global _start

_start: mov X0, #1
    ldr     X1, =hello
    mov     X2, #13
    mov     X8, #64
    svc     0

    mov     X0, #0
    mov     X8, #93
    svc     0

.data
hello: .ascii  "Hello World!\n"

I cannot event assemble this program using clang hello.s on MacOS, I get this error:

Undefined symbols for architecture arm64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I assume that this error is because I have not told clang that it should use Linux as target.

How can I cross assemble the above "Hello World" to Linux Arm64 from MacOS on Arm64 using the built in clang?

I want to be able to run the Linux binary in a Arm64 Docker container on MacOS Arm64.

CodePudding user response:

You will need lld or some other linker that can output ELF binaries, as Xcode only ships with Apple's ld64, which is limited to Darwin targets. Once you have lld in your path, you can build your assembly file with:

clang --target=arm64-linux-gnu -fuse-ld=lld hello.s -nostdlib

Of course, if you want to use libraries or eventually compile C code and include header files, you will have to either find or build an SDK to pass to clang with --sysroot. I'm not aware of any standard process for doing this, but I've had some success with just pulling public deb files from Ubuntu/Debian package mirrors and unpacking them into one folder.

  • Related