4 ms·
I was most interested to see how the fork syscall works: sys fork br new process code / old process code continues here / r0 contains new proce
by jepler 11y ago
I was most interested to see how the fork syscall works:
sys fork
br new process code
/ old process code continues here
/ r0 contains new process pid
/ c flag set if fork failed
so the if(fork() == 0) { child code } else { parent code } of modern fork is magic right inside the fork syscall (which just has to increment the return address by the size of one br instruction before returning to the parent)
I guessed some of this from the source, but confirmed more details in https://archive.org/stream/bitsavers_attunixUNIedJun72_7765885/UNIX_Programmers_Manual_2ed_Jun72_djvu.txt https://archive.org/stream/bitsavers_attunixUNIedJun72_77658... -- syscalls were already in section II of the manual at that time, fwiw.
- tonyg 11y agoEchoes of this idea still persist in modern systems. For example, from http://uninformed.org/?v=1&a=1&t=txt http://uninformed.org/?v=1&a=1&t=txt discussing PowerPC OS X system calls: "An interesting feature of Mac OS X is that a successful system call will return to the address 4 bytes after the end of 'sc' instruction and a failed system call will return directly after the 'sc' instruction. This allows you to execute a specific instruction only when the system call fails. The most common application of this feature is to branch to an error handler, although it can also be used to set a flag or a return value." A similar idea crops up in ARM's exception/interrupt table, where on exception N, control passes to the instruction at memory location N*4. Since instructions are all 4 bytes wide, you usually put a branch instruction in each slot that jumps to the real handler routine.
- JdeBP 11y agoThey're not so much echoes as a continuing necessity. System calls in UNIX-style operating system APIs generally return two integer values, a file descriptor/character count/ID/whatever and an error code; and because the twain are largely mutually exclusive the system call mechanism usually (dependent from the architecture of course) has some way of marshalling that into one processor register, be it using alternative return addresses or a flag bit such as the carry flag in the status word. The OS/2 Control Program API and the Windows NT Native API return the error codes explicitly from the HLL wrapper functions, the (for example) open file handle returned from DosOpen() being an integer passed by reference, and their system call marshalling is thus somewhat different. It helps that calling conventions such as APIENTRY32 (http://homepage.ntlworld.com./jonathan.deboynepollard/FGA/function-calling-conventions.html#APIENTRY32 http://homepage.ntlworld.com./jonathan.deboynepollard/FGA/fu...) lend themselves easily to a treat-the-stacked-arguments-as-a-structure system, moreover. I implemented a similar API once, marshalling by-reference system call arguments through processor registers using a pass-by-value-return scheme.