简体   繁体   English

使用 MacOS clang 汇编程序交叉汇编 Linux Arm64

[英]Cross assemble Linux Arm64 using MacOS clang assembler

I am trying to write Assembly on MacOS using the default clang assembler.我正在尝试使用默认的clang汇编程序在 MacOS 上编写程序集。

I got this small "Hello World" working for MacOS on the same machine:我在同一台机器上得到了这个用于 MacOS 的小“Hello World”:

.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 .现在,我尝试使用 64 位 ARM 汇编语言编程一书中的 Linux 的“Hello World”。 It is basically the same program, but the sys-calls is for Linux:它基本上是相同的程序,但系统调用是针对 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:我无法在 MacOS 上使用clang hello.s组装这个程序,我得到这个错误:

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.我假设这个错误是因为我没有告诉clang它应该使用 Linux 作为目标。

How can I cross assemble the above "Hello World" to Linux Arm64 from MacOS on Arm64 using the built in clang?我如何使用内置的 clang 从 Arm64 上的 MacOS 将上面的“Hello World”交叉组装到 Linux Arm64?

I want to be able to run the Linux binary in a Arm64 Docker container on MacOS Arm64.我希望能够在 MacOS Arm64 上的 Arm64 Docker 容器中运行 Linux 二进制文件。

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.您将需要lld或其他一些可以 output ELF 二进制文件的 linker,因为 Xcode 仅随 Apple 的ld64一起提供,仅限于达尔文目标。 Once you have lld in your path, you can build your assembly file with:一旦你的路径中有lld ,你就可以构建你的程序集文件:

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 .当然,如果您想使用库或最终编译 C 代码并包含 header 文件,您将必须查找或构建一个 SDK 以使用 --sysroot 传递给--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.我不知道执行此操作的任何标准过程,但我已经取得了一些成功,只是从 Ubuntu/Debian package 镜像中提取公共 deb 文件并将它们解压缩到一个文件夹中。

After the answer to Siguza, the difficult part was to find a linker that could do the job.在回答 Siguza 之后,困难的部分是找到可以完成这项工作的linker

This is what finally worked for me.这就是最终对我有用的东西。

Install macos cross toolchain with:使用以下命令安装macos 交叉工具链

brew install aarch64-unknown-linux-gnu

After that I have this binary that can be added to PATH:之后我有了这个可以添加到 PATH 中的二进制文件:

/opt/homebrew/Cellar/aarch64-unknown-linux-gnu/11.2.0/bin/aarch64-unknown-linux-gnu-ld

Then I could build the binary with:然后我可以构建二进制文件:

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

And I could verify the binary by using this Dockerfile:我可以使用这个 Dockerfile 来验证二进制文件:

FROM scratch
ADD a.out /bin/
ENTRYPOINT ["/bin/a.out"]

Build a container with:构建一个容器:

docker build -t app .

Run it and get the output:运行它并获得 output:

docker run app
Hello World!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM