Linux has a stable syscall ABI, but NT doesn't, Windows just ensure Win32 ABI is stable, which will not trap into kernel space immediately. Lower level functions of Windows like nt.dll might change between Windows Update or Windows Editions.

I want to know for other kernels, like FreeBSD kernel or Mach, do they provide stable syscalls or just provide stable ABI of POSIX interface?

  • In practice, the NT Native API has been pretty much stable for quarter of a century.
    – JdeBP
    Commented Oct 4, 2018 at 6:55
  • Windows NT system call ABI is not stable at all, the system call numbers are completely changed between releases. See sourceforge.net/u/low-power/hello-world/ci/master/tree/…
    – Low power
    Commented Jan 14, 2019 at 4:47
  • @Lowpower I do know Windows can change its syscall number, that's why it never recommend you to lower level API than Win32. But how about other kenrels, like FreeBSD kernel? Its manual pages contains syscall-level C warpper functions, it seems to be stable, if it's not, old programs might break on newer editions. Commented Jan 15, 2019 at 1:28
  • System call ABI of kFreeBSD seems stable (than many others), but they don't guarantee (see The kernel works, but ps(1) does not). I actually successfully started FreeBSD 10.4 userland with a FreeBSD 12 kernel, however some programs throw syscall errors like 'Invalid argument' on start up.
    – Low power
    Commented Jan 15, 2019 at 9:22

1 Answer 1


Generally, the answer is no, although it is likely developers of operating systems will be nice for compatibility reasons. You should not rely on it though.



No compatibility for API and ABI is guaranteed from one to the next major release, though an effort is made to make the upgrade process and source code changes as untroubled as possible.



No, and syscalls without going through libc will be disallowed by force.

I already made it difficult to call execve() directly in a few ways. The kernel must be entered via the exact syscall instruction, inside the libc syscall stub. Immediately before that syscall instruction, the SYS_execve instruction is loaded into a register. On some architectures, the PLT-reachable stub performs a retguard check, which can be triggered by a few methods. Stack pivots are also mostly prevented because of other checks. It is not possible to enter via the SYS_syscall (syscall register = 0) case either.


System call origin checking has been introduced since late 2019.



This system call is useful for testing new system calls that do not have entries in the C library. It should not be used in normal applications.



No, and there have been previous breaks before.

Apple does not support statically linked binaries on Mac OS X. A statically linked binary assumes binary compatibility at the kernel system call interface, and we do not make any guarantees on that front. Rather, we strive to ensure binary compatibility in each dynamically linked system library and framework.


An answer by eskimo, an Apple staff member, has confirmed this continues to be the case.

Apple’s tools support static libraries but they do not support statically linking an entire executable [1]. All programs must link to the System framework (aka libSystem) in order to access the kernel. Apple only guarantees binary compatible at that layer. A statically linked executable would have to make system calls directly, and we do not guarantee binary compatible there.


Solaris and illumos


Solaris and Illumos, the only officially supported method of making system calls is also through the C library


For a more authoritative source, this email from 2010 says definitively that manual syscalls are not supported.

Andrew, there's not really an "offical" way ro reserve or even reclaim a
syscall number.

syscall numbers are an undocumented / uncommitted interface.

We do not support 3rd-party system calls and we never have. You are, as an ISV, on your own when you want that, and you have to face that you're using an uncommitted interface and breakage (by a kernel
patch) may occur. We do not notify 3rd-party people if something in the system call table
changes. It's not a stable interface.



No, probably. I couldn't find anything about the syscall layer on AIX. syscall (indirect system calls) is not supported here. System calls appear to be able to be extended dynamically on AIX.

Subject: syscall on RS/6000 for XView 3.0

I read the information in info by searching on the string syscall and looking at all the information. However some of the information I see may not be available outside IBM. Here is my retyping of what I found - not guaranteed to be accurate.
Item Number: Q557045
... Question:
We are try to port an application that runs on a SUN. One of the
programs uses a routine called 'syscall' to do its low-level
read, write and fnctl's. What, if any, can we use on the RS/6000
to accomplish this task. Without this or an equivalent feature we will
have to write an EXTENSIVE work-around.

There aren't any routines that you can use on the RS/600 to duplicate
the function of the "syscall" system call. The "syscall" system call
is an indirect system call on BSD. That is, the first argument
indicates which other system call the kernel should perform and
subsequent arguments are passed to the other call. This is inherently
non-portable, since the system call numbers become visible at
user-level, instead of being hidden in a C wrapper in libc. The
system call numbers are defined in syscall.h (which is not included in
AIX V3). [since the kernel can be and is extended dynamically]

To port code which uses this call, you need to understand which calls
are being made and write your own version of syscall which basically
consists of a switch statement on the first argument, and then calls
the appropriate system call with the correct number of arguments.

Suitable use of varagrs.h (stdarg.h) may be needed depending on the
systems calls being made.


ld also warns that static linking is incompatible between versions

Note: By using either of these [noautoimp or nso] flags, you can statically link a shared object file into an application. Any application that is statically linked is not binary portable from any fix or release level to any other fix or release level.


See also: https://blog.firetree.net/2005/07/21/static-linking-on-aix/

  • 1
    In practice, however, FreeBSD's compatibility is remarkably good, at least as measured by the ability to run old binaries under new OS releases. I have one instance running a FreeBSD 9 FAMP-stack website under a FreeBSD 14 kernel. That's nine years and five full-version releases removed. FreeBSD also provides compatibility "shim" libraries in the package tree, currently going back as far as version 5 for the amd64 architecture, and back to version 4 for i386. Even so, my v9-under-v14 instance does not need them, since everything the FAMP stack needs is already sufficiently compatible.
    – Jim L.
    Commented Nov 4, 2023 at 23:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .