The HyperNews Linux KHG Discussion Pages

## Explaining syscall macros

  Forum: How System Calls Work on Linux/i86
  Re: would be nice to explain syscall macros (Tim Bird)
  Keywords: syscall
  Date: Mon, 18 May 1998 16:49:41 GMT
  From: Wormo <sjl@zorbas.ece.ucsb.edu>

# The _syscallN Family of Macros (By which, I mean the macros _syscall0,...,_syscall5) ## Location: include/asm-i386/unistd.h ## Definition: (or rather a general rule for the definitions, if you want to see all 6 definitions written out in their entirety go look in the source) #define _syscallN(type,name,type1,arg1,...,typeN,argN) \ type name(type1 arg1,...,typeN argN) \ { \ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name), \ "b" ((long)(arg1)), \ . . Nth CONSTRAINT ((long)(argN))); \ if (__res >= 0) \ return (type) __res; \ errno = -__res; \ return -1; \ } where N the number of arguments the system call takes and is a number from 0-5, and Nth CONSTRAINT is the appropriate constraint for the input operand corresponding to the Nth argument and is assigned in order according to the following table:
    N      Constraint       Meaning
    1      "b"             value placed in %ebx register
    2      "c"             value placed in %ecx register
    3      "d"             value placed in %edx register
    4      "S"             value placed in %esi register
    5      "D"             value placed in %edi register
info gcc for further details on this asm syntax (try node Extended Asm) ## Example usage: static inline _syscall2(int,clone,unsigned long, flags,char *,esp) Expands to: static inline int clone(unsigned long flags, char * esp) { long __res; __asm__ volatile ("int $0x80" : "=a" (__res) : "0" (__NR_##name), "b" ((long)(flags)), "c" ((long)(esp))); if (__res >= 0) return (int) __res; errno = -__res; return -1; } ## Purpose: Each of these macros is a template used to create the function definition for system calls with the corresponding number of arguments. A function generated from this macro: places the appropriate system call number into %eax, loads parameters as needed into the other general registers (%ebx, %ecx, %edx, %esi, %edi in that order), does an inturrupt 0x80 which has the general system_call() asm function from arch/i386/kernel/entry.S as its interrupt handler, lets system_call() call the specific system call code (generally in a function named something like sys_NameOfThisSyscall), and, after the specific code is finished and system_call() returns, processes the return code that was returned in %eax -- returning the result if system call was successful, or returning -1 and setting errno appropriately if system call was unsuccessful. Hack on happy linuxites, --Wormo