# Question about code snippet on syscall(struct trapframe *)



## revflash (Dec 10, 2017)

Hi,

I'm working on a lecture about FreeBSD rootkits. I was reading the kernel source code and trying to understand the syscall flow from `int 0x80` until the point where the syscall is actually executed. As far as i could understand, the execution begins with 


```
IDTVEC(int0x80_syscall)
  pushl  $2  /* sizeof "int 0x80" */
  pushl  $0  /* tf_trapno */
  pushal
  pushl  $0
  movw  %ds,(%esp)
  pushl  $0
  movw  %es,(%esp)
  pushl  $0
  movw  %fs,(%esp)
  SET_KERNEL_SREGS
  cld
  FAKE_MCOUNT(TF_EIP(%esp))
  pushl  %esp
  call  syscall
```

where the kernel creates a trapframe and passes it as a parameter to the syscall function. Inside the syscall function, i found this code snippet that made me confused:


```
void
syscall(struct trapframe *frame)
{
      ...
      params = (caddr_t)frame->tf_esp + sizeof(int);
      ...
}
```

Where is the kernel setting tf_esp and why is it adding 4 bytes to it? I found this paper and the autor explains:


> First we retrieve the value of ESP before INT 0x80 was issued. This value can be found in the trap stack frame. Since the processor pushed the value of SS onto the stack before it pushed ESP we need to add 32 bits (PUSHL pushed SS as a 32 bit value) to get to the parameters



I don't understand what it means. I thought the reason was because the FreeBSD kernel uses the C calling convention, but it seems i'm wrong.

Thank you!


----------



## SirDice (Dec 11, 2017)

Developer's handbook: 11.3. System Calls


----------

