A general overview of what happens before main() (2019)
embeddedartistry.com
embeddedartistry.com
Statically linked code is permissible on Intel.
This is a reflection of historical differences in opinion about whether the stable ABI for an OS kernel should be the kernel itself (ala Linux), libc (ala Solaris or OpenBSD), or a language-agnostic library (Windows NT's ntdll).
macOS seems to be in a transition period toward the Windows model, with libSystem providing trampolines into the kernel. However, they don't yet enforce this model like OpenBSD does, so if you're willing to risk the syscall numbers changing you can do without libSystem.
Here's an example, lightly adapted from <https://john-millikin.com/unix-syscalls#darwin-x86-64>:
.data
.set L_STDOUT, 1
.set L_SYSCALL_EXIT, 0x2000001
.set L_SYSCALL_WRITE, 0x2000004
L_message:
.ascii "Hello, world!\n"
.set L_message_len, . - L_message
.text
.global start
start:
# write(STDOUT, message, message_len)
mov $L_SYSCALL_WRITE, %rax
mov $L_STDOUT, %rdi
lea L_message(%rip), %rsi
mov $L_message_len, %rdx
syscall
# exit(0)
mov $L_SYSCALL_EXIT, %rax
mov $0, %rdi
syscall
Compile (assemble?) it to a static binary: $ as -arch x86_64 hello.S -o hello.o
$ ld -arch x86_64 -o hello -static hello.o
$ file hello
hello: Mach-O 64-bit executable x86_64
It runs fine: $ ./hello
Hello, world!Thanks for commenting. I had read your article via another comment here. I had not thought about the syscall approach before, because as you note Apple does not (well, did not previously) guarantee syscall stability.
I assume my understanding of static linking is too simplistic though.
This distinction is related to but not the same as statically or dynamically linking an individual dependency; only if all dependencies are statically linked can an executable then be statically linked.
https://github.com/jart/cosmopolitan/blob/master/libc/sysv/s...
https://github.com/jart/cosmopolitan/blob/master/libc/sysv/s...
We do everything static. Even on Apple x86 and M1.
A C runtime is often provided by the same project as the C standard library (the other viable option is to have it provided by the compiler project).
Not all. Typically stdarg.h is not. On Linux, <sys/*> is not.
The presence in your binary only means that crt0.o was statically linked (may be an expectation of the loader on your system). If you linked against a static libc, you would also see those symbols as part of the binary.
I'm pretty sure it works that way on windows too, but they call the symbol mainCRTStartup or some such.
The point I am making is that crt0.o usually comes from libc, even if it is linked separately.
I suspect that the loader expects the ELF entry point to be an address in the application, not a dynamically linked library, which is why crt0.o must be statically linked.
Many computer users run a modified version of the GNU system every day, without realizing it. Through a peculiar turn of events, the version of GNU which is widely used today is often called "Linux", and many of its users are not aware that it is basically the GNU system, developed by the GNU Project.
There really is a Linux, and these people are using it, but it is just a part of the system they use. Linux is the kernel: the program in the system that allocates the machine's resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. Linux is normally used in combination with the GNU operating system: the whole system is basically GNU with Linux added, or GNU/Linux. All the so-called "Linux" distributions are really distributions of GNU/Linux.
It's too bad RMS got sidetracked with Hurd. But, the GNU system now runs with several kernels - the Linux kernel is just the most developed and best known one.
Many computer users run a modified version of the Darwin system every day, without realizing it. Through a peculiar turn of events, the version of Darwin which is widely used today is often called "macOS", and many of its users are not aware that it is basically the Darwin system, developed by Next Computer.
There really is a macOS, and these people are using it, but it is just a part of the system they use. XNU is the kernel: the program in the system that allocates the machine's resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. Darwin is normally used in combination with the macOS operating system: the whole system is basically Darwin with macOS added, or Darwin/macOS. All the so-called "macOS" versions are really versions of Darwin/macOS.
---
Apple's engineers still refer to the OS as Mac OS X. Ventura is technically 10.18, despite the 13 major number in their marketing.
No.