Linux有稳定的系统调用ABI,但NT没有,Windows只是确保Win32 ABI稳定,不会立即陷入内核空间。 Windows 的较低级别功能(如 nt.dll)可能会在 Windows 更新或 Windows 版本之间发生变化。
我想知道对于其他内核,例如 FreeBSD 内核或 Mach,它们是否提供稳定的系统调用或仅提供 POSIX 接口的稳定 ABI?
答案1
一般来说,答案是不,尽管出于兼容性原因,操作系统开发人员可能会很友好。但你不应该依赖它。
自由BSD
不。
尽管我们努力使升级过程和源代码更改尽可能不受干扰,但不保证 API 和 ABI 从一个版本到下一个主要版本的兼容性。
https://wiki.freebsd.org/VendorInformation
开放BSD
不可以,未经通过的系统调用libc
将被强制禁止。
我已经通过几种方式使直接调用 execve() 变得困难。必须通过 libc 系统调用存根内的确切系统调用指令进入内核。在该系统调用指令之前,SYS_execve 指令被加载到寄存器中。在某些架构上,PLT 可到达的存根执行 retguard 检查,可以通过几种方法触发。由于其他检查,堆栈枢轴也大多被阻止。也不可能通过 SYS_syscall(系统调用寄存器 = 0)进入。
https://marc.info/?l=openbsd-tech&m=169841790407370&w=2
引入了系统调用来源检查自2019年底以来。
网络BSD
不。
此系统调用对于测试 C 库中没有条目的新系统调用非常有用。不应在正常应用中使用它。
https://man.netbsd.org/syscall.2
苹果系统
没有,而且已经有过之前的休息时间。
Apple 不支持 Mac OS X 上的静态链接二进制文件。静态链接二进制文件假定内核系统调用接口处的二进制兼容性,我们对此不做任何保证。相反,我们努力确保每个动态链接的系统库和框架的二进制兼容性。
https://developer.apple.com/library/archive/qa/qa1118/_index.html
的回答爱斯基摩人苹果公司的一名工作人员证实,情况仍然如此。
Apple 的工具支持静态库,但不支持静态链接整个可执行文件 [1]。所有程序都必须链接到系统框架(又名
libSystem
)才能访问内核。 Apple 仅保证该层的二进制兼容。静态链接的可执行文件必须直接进行系统调用,我们不保证那里的二进制兼容。
https://developer.apple.com/forums/thread/706419
Solaris 和 illumos
不。
Solaris 和 Illumos,唯一官方支持的系统调用方法也是通过 C 库
https://utcc.utoronto.ca/~cks/space/blog/programming/GoCLibraryAPIIssues
作为更权威的来源,这封 2010 年的电子邮件明确表示不支持手动系统调用。
Andrew,并没有真正的“官方”方式来保留甚至回收
系统调用号。系统调用号是一个未记录/未提交的接口。
我们不支持第三方系统调用,而且从来没有支持过。作为 ISV,当您需要时,您只能靠自己,而且您必须面对您正在使用未提交的接口,并且
可能会发生损坏(通过内核补丁)。如果系统调用表中的某些内容
发生变化,我们不会通知第三方人员。这不是一个稳定的界面。
https://www.cs.cmu.edu/afs/gco/archive/pipermail/port-solaris/2010-November/000009.html
AIX
不,可能是。我在 AIX 上找不到任何有关系统调用层的信息。syscall
这里不支持(间接系统调用)。系统调用似乎能够在 AIX 上动态扩展。
主题:XView 3.0 的 RS/6000 上的系统调用
我通过搜索字符串 syscall 并查看所有信息来读取 info 中的信息。然而,我看到的一些信息可能无法在 IBM 之外获得。这是我对我发现的内容的重新输入 - 不保证准确。
------------ 10/02/91 需要 AIX 等效的 SUN 系统调用例程
项目编号:Q557045
... 问题:
我们正在尝试移植在 SUN 上运行的应用程序。其中一个
程序使用名为“syscall”的例程来执行其低级
读取、写入和 fnctl 操作。如果有的话,我们可以在 RS/6000 上使用什么
来完成这项任务?如果没有这个或等效的功能,我们将
不得不编写一个广泛的解决方法。答:
RS/600 上没有任何例程可以用来复制
“syscall”系统调用的功能。 “syscall”系统调用
是 BSD 上的间接系统调用。也就是说,第一个参数
指示内核应执行哪个其他系统调用,
后续参数将传递给其他调用。这本质上是
不可移植的,因为系统调用号在
用户级别变得可见,而不是隐藏在 libc 的 C 包装器中。系统
调用号在 syscall.h 中定义(
AIX V3 中不包含该文件)。 [因为内核可以并且是动态扩展的]要移植使用此调用的代码,您需要了解
正在进行哪些调用并编写您自己的系统调用版本,该版本基本上
由第一个参数上的 switch 语句组成,然后
使用正确数量的参数调用适当的系统调用。
根据所进行的系统调用,可能需要适当使用 varagrs.h (stdarg.h) 。
http://www.verycomputer.com/176_244b08fbb92e184f_1.htm
ld
还警告静态链接在版本之间不兼容
笔记: 通过使用其中任何一个 [
noautoimp
或者nso
] 标志,您可以将共享对象文件静态链接到应用程序中。静态链接的任何应用程序都不能从任何修复或发布级别二进制移植到任何其他修复或发布级别。
https://www.ibm.com/docs/en/aix/7.3?topic=l-ld-command
也可以看看:https://blog.firetree.net/2005/07/21/static-linking-on-aix/