2

我正在内联系统调用。是的,我知道这是有问题的,但我有充分的理由。我已经大量追踪了我的错误,我只是想问为什么__NR_open在这个 arm64 Arch Linux 系统上消失了?

5.0.1-1-ARCH #1 SMP Sun Mar 10 15:08:34 MDT 2019 aarch64 GNU/Linux

同样,我的代码是内联系统调用。这种内联方法适用于另一个X86_64系统,并且内联mmap()确实适用于该系统。但是,在这个 arm64 Arch Linux 上内联open()失败并出现EFAULT

追踪我的错误,首先,__NR_open甚至没有在这个构建环境中定义。其次,常规open()调用open64(),它执行x8 设置为 #56的svc指令__NR_openat。第三,__NR_open通常定义为 5,并且该数字已重新用于__NR_setxattr。这解释了EFAULT

基本上,open()在这个系统的用户库中被转换成openat()并且__NR_open系统调用已经完全消失,由一个新的系统调用接管。我不明白的是__NR_open是在 arm64 的规范源代码中定义的,但不是在这个 Arch Linux arm64 系统上。

我的错误修复很简单:改为内联openat()。但我的问题是为什么它被删除了,为什么它不被认为是从 Linux POV 中破坏的?我在想 Linus 说我们不会破坏用户空间!而且我不是从 POSIX POV 考虑这个问题。事实上,Linux 编程接口至少没有明确地涵盖此删除。

4

1 回答 1

10

您正在查看的文件是arch/arm64/include/asm/unistd32.harm32 兼容模式的系统调用定义。

本机 aarch64 的系统调用定义来自通用系统调用表include/uapi/asm-generic/unistd.h,您可以看到它没有定义__NR_open。系统调用没有被删除——它在 aarch64 上从未存在过。

__NR_open通用表中未定义的原因是openat(2)系统调用是稍后引入的,并且是功能的严格超集,因此提供该系统调用的架构端口(在引入之后创建)_NR_open没有意义- 这是多余的. POSIX函数由用户空间 C 库提供,调用系统调用。openat(2)open()openat(2)

之前存在的旧架构端口(例如 x86 和arm32 openat(2))必须继续包含. 这种担忧不适用于新的架构移植——“破坏用户空间”的保证是,如果它在昨天工作,那么它今天也会工作,但它并没有说如果它在现有架构上工作,它可以重新编译并在一些新的架构上工作建筑学。open(2)open(2)

于 2019-03-28T23:08:09.233 回答