The HyperNews Linux KHG Discussion Pages

More: Explaining syscall macros

Forum: How System Calls Work on Linux/i86
Re: Note 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:
  1. places the appropriate system call number into %eax,
  2. loads parameters as needed into the other general registers (%ebx, %ecx, %edx, %esi, %edi in that order),
  3. does an inturrupt 0x80 which has the general system_call() asm function from arch/i386/kernel/entry.S as its interrupt handler,
  4. 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,

  5. 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.
  6. Hack on happy linuxites,
    --Wormo