GAS组装的QEMU中运行的ARM64 ELF可执行文件的对齐要求

GAS组装的QEMU中运行的ARM64 ELF可执行文件的对齐要求,arm,clang,elf,qemu,gnu-assembler,Arm,Clang,Elf,Qemu,Gnu Assembler,我有一个ARM64程序,当我运行它时,它会立即进行汇编,但会出现故障: // GNU Assembler, ARM64 Linux .bss .lcomm ARRAY, 16 .text .global _start _start: mov x8, 93 // exit sys num mov x0, 0 // success svc 0 从蛮力试错中,我通过添加以下行来修复它: // GNU Assembler, ARM64 Linux .bss .lc

我有一个ARM64程序,当我运行它时,它会立即进行汇编,但会出现故障:

// GNU Assembler, ARM64 Linux

.bss

.lcomm ARRAY, 16

.text

.global _start

_start:
    mov x8, 93 // exit sys num
    mov x0, 0 // success
    svc 0
从蛮力试错中,我通过添加以下行来修复它:

// GNU Assembler, ARM64 Linux

.bss

.lcomm ARRAY, 16

.p2align 12 // why?

.text

.global _start

_start:
    mov x8, 93 // exit sys num
    mov x0, 0 // success
    svc 0
它仅适用于
.p2align 12
(相当于
.balign 4096
)或更高版本,否则它仍会使用
.p2align 11
或更低版本的值进行故障隔离。我知道填充可能会解决一些未对齐的问题,但我不明白为什么它的值会如此之大,就像我所看到的所有其他ARM64示例一样,无论是手工编写的还是由编译器生成的,通常在
.text
部分之前只插入一个
.p2align 2
,那么为什么我的小程序需要
.p2align 12

此外,我注意到所需的填充大小与
.text
部分的长度成反比。对于上面的
.p2align 12
这样的小程序,需要使它们运行时不出现分段错误,但是
.text
段越长,我可以填充的内容就越小,对于有数千条指令的程序,我根本不需要添加任何填充

我在x86_64 macOS机器上,但我在Docker容器中编译和运行这些程序,Docker容器是从这个Dockerfile构建的:

FROM ubuntu:20.04
RUN apt-get update && apt-get -y install clang qemu gcc-aarch64-linux-gnu
我正在使用以下工具编译和运行ARM64程序:

clang -nostdlib -fno-integrated-as -target aarch64-linux-gnu -s program.s -o program.out && ./program.out

我觉得我遗漏了一些关于GAS、QEMU、ARM64或ELF可执行文件的关键信息,但我不知道它是什么。

QEMU被数据部分的程序标题弄糊涂了:

    LOAD off    0x00000000000000c0 vaddr 0x00000000004100c0 paddr 0x00000000004100c0 align 2**16
         filesz 0x0000000000000000 memsz 0x0000000000000010 flags rw-
无法在该地址实际映射一些可写内存;segfault来自QEMU本身,它试图将BSS设置为零


由于该程序在真正的AArch64 Linux内核上运行良好,因此这是一个QEMU错误。我已经报告过了,所以我们将看看是否有人提出了修复方案。

它在本机aarch64 linux机器上组装并运行时不会出错。这可能是qemu的错误或限制。我没有看到在您的命令中调用任何docker或qemu命令:
clang-nostlib-fno integrated as-target aarch64 linux gnu-s program.s-o program.out&./program.out
。我假设您的docker容器运行的是UbuntuFocusx86_64,因此希望qemu-system-aarch4用于在aarch64 Linux发行版中运行您的程序。我遗漏了什么吗?@Frant我正在Ubuntu 20.04 x86_64 Docker容器中运行
clang
命令。编译后的aarch64 ELF程序运行时没有任何额外的命令行参数,因此我假设Ubuntu识别出该程序是aarch64 ELF文件,并使用QEMU作为CPU仿真层自动启动它。我可能错了,我不知道x86_64 Ubuntu如何运行aarch64 ELF文件。@pretzelhammer:我忘了提到是的,第一个版本导致了segfault,但第二个版本没有。@artless noise:我刚刚检查过,而且似乎.bss位于.text之后:1.text 0000000 c 0000000000 40010c 0000000000 40010c 00000 10c 22内容,ALLOC,LOAD,READONLY,代码2.bss 000000 10 0000000000 410118 0000000000 410118 00000118 23`ALLOC