【问题标题】:GCC compilation with nostdlib flag for Aarch64 platform用于 Aarch64 平台的带有 nostdlib 标志的 GCC 编译
【发布时间】:2018-09-13 16:44:25
【问题描述】:

我正在尝试在 Aarch64 平台上编译带有 nostdlib 标志的二进制文件。

我已经通过这种方式在x86-64平台上成功处理了:

    void _start() {

    /* main body of program: call main(), etc */

    /* exit system call */
    asm("movl $1,%eax;"
        "xorl %ebx,%ebx;"
        "int  $0x80"
    );
}

在 aarch64 平台上有没有类似的东西可以做同样的事情?(特别是系统退出调用)

【问题讨论】:

  • 是的。可能是svc 指令,但具体细节取决于您的操作系统。

标签: gcc assembly arm system-calls arm64


【解决方案1】:

下面的示例应该在 aarch64-linux-gnu 系统上运行 - 它确实可以在我的 x86_64 linux 系统上运行 qemu-aarch64 3.0。

以我的拙见,用于学习目的的最简洁/松散耦合的信息来源是musl-libc源代码:

  • syscall_arch.h 确实包含要使用的 _syscall 函数,具体取决于给定系统调用所需的参数数量,
  • syscall.h.in 确实包含所有系统调用的定义。

然后我们应该使用:

static inline long __syscall1(long n, long a)
{
    register long x8 __asm__("x8") = n;
    register long x0 __asm__("x0") = a;
    __asm_syscall("r"(x8), "0"(x0));
}

和 __NR_exit:

#define __NR_exit 93
#define __NR_exit_group 94

C 中的一个基本示例是 syscall-exit.c:

#include "syscall_arch.h"
#include "syscall.h.in"

int main(void)
{
   // exiting with return code 1.
    __syscall1(__NR_exit, 1);

   // we should have exited.
   for (;;);
}

编译/执行/检查返回码:

/opt/linaro/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc -static -O0 -o exit-syscall exit-syscall.c
qemu-aarch64 exit-syscall
echo $?
1

仔细查看生成的 main() 和 __syscall1() 代码:

/opt/linaro/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-objdump  -D exit-syscall > exit-syscall.lst

看起来像:

0000000000400554 <main>:
400554:   a9bf7bfd    stp x29, x30, [sp, #-16]!
400558:   910003fd    mov x29, sp
40055c:   d2800021    mov x1, #0x1                    // #1
400560:   d2800ba0    mov x0, #0x5d                   // #93
400564:   97fffff4    bl  400534 <__syscall1>


0000000000400534 <__syscall1>:
400534:   d10043ff    sub sp, sp, #0x10
400538:   f90007e0    str x0, [sp, #8]
40053c:   f90003e1    str x1, [sp]
400540:   f94007e8    ldr x8, [sp, #8]
400544:   f94003e0    ldr x0, [sp]
400548:   d4000001    svc #0x0
40054c:   910043ff    add sp, sp, #0x10
400550:   d65f03c0    ret

有关详细信息,请参阅文档“Procedure Call Standard for the ARM 64-bit Architecture(AArch64)”。

因此,与您的 x86_64 代码等效的 Aarch64 将是 exit-asm.c :

void main(void) {

    /* exit system call  - calling NR_exit with 1 as the return code*/
    asm("mov x0, #1;"
        "mov x8, #93;"
        "svc #0x0;"
    );

    for (;;);
}


/opt/linaro/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc -static -o example example.c 
qemu-aarch64 example
echo $?
1

请注意,exit() 的 glibc 实现确实会在调用 __NR_exit 之前调用 __NR_exit_group。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多