William Studart
William Studart

Reputation: 331

System call Table in x86 (ia32)

I'm studying how system calls are implemented in the Kernel code, and I'm focusing in the x86 architecture, however, I'm having a tough time understanding the assembly code, and the part where it acesses (or call the function?) of the system call table (the entry.S file, as far as I understand, uses the macros to "prepare" for the system call), and the part that's a mystery for is:

ia32_do_call:
  IA32_ARG_FIXUP
  call *ia32_sys_call_table(,%rax,8) # xxx: rip relative

Since I'm using the website lxr.free-electrons.com, I used the free-text search to see how is the function implemented for further understanding. I've come across this:

const sys_call_ptr_t ia32_sys_call_table[__NR_ia32_syscall_max+1] = {
   /*
    * Smells like a compiler bug -- it doesn't work 
    * when the & below is removed.
    */
    [0 ... __NR_ia32_syscall_max] = &compat_ni_syscall,
#include <asm/syscalls_32.h>
};

What's happening here?

Upvotes: 3

Views: 1846

Answers (1)

Nathan Chappell
Nathan Chappell

Reputation: 2436

I was a bit surprised by this file as well, so I'll leave a few pointers to help you out if you get here.

First of all, sys_call_ptr_t is defined in include/asm/syscall.h as:

typedef long (*sys_call_ptr_t)(const struct pt_regs *);

Therefore ia32_sys_call_table is an array of function pointers, as we expect. Next, this array is initialized with a gcc extension known as designated initializers (thanks to this question). The first part of the initialization sets each entry of the table to point to a function called sys_ni_syscall (I'm pretty sure, it seems to get created through a bunch of macros...). This is defined in a file kernel/sys_ni.c:

/*                                                   
 * Non-implemented system calls get redirected here. 
 */                                                  
asmlinkage long sys_ni_syscall(void)                 
{                                                    
    return -ENOSYS;                                  
}                                                    

Finally, the inclusion of the file <asm/syscalls_32.h> can be understood by looking at two things. First of all, go to entry/syscalls/, and run

bash syscalltbl.sh syscall_32.tbl gen.c

and take a look at the contents of gen.c. Now, look at this macro from entry/syscall_32.c:

#define __SYSCALL_I386(nr, sym) [nr] = __ia32_##sym,

At this point, with maybe a little more grepping around, this file should not be so mysterious.

Upvotes: 1

Related Questions