1

I came across this wikibook which shows that there can be 7 arguments passed to syscall, and I want to understand what is the purpose of each one of them.

This is not specified in the man page.
Also, I have found a table of the arguments you can pass to each syscall but I don't necessarily understand the common ground between them.

Ideally, I'm looking for an answer that specifies

arg #1 - pid  
arg #2 - ... 

Architecture is x86-64.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Eliran Turgeman
  • 1,526
  • 2
  • 16
  • 34

1 Answers1

4

The table you linked to provides the list of arguments you're asking for.

I think what may be confusing you is that syscall doesn't perform a single operation. Rather, it's a general-purpose API for anything you might want to ask the kernel to do -- open a file, map memory, fork a new process, and so on.

The specific operation you want the kernel to do is selected using the syscall number. Just picking the first one from the table, syscall 0 (known as sys_read) reads from a file.

Obviously, the operations performed by the different syscalls require different arguments. Staying with the sys_read example, we see in the table that it takes three arguments: The file descriptor (fd), a pointer to a buffer (buf) and a number of bytes to read (count). So if you wanted to call this syscall, you would do it as follows:

#include <sys/syscall.h>

// Assuming these have been initialized appropriately.
unsigned int fd = ...;
char * buf = ...;
size_t count = ...;

syscall(SYS_read, fd, buf, count);

This answer has more information on when you might want to choose to use syscall. The short version is that the reasons to use syscall are few and far between.

Edit: As @PeterCordes points out, syscall numbers differ between ABIs, so you should use the constants defined in sys/syscall.h instead of hardcoding syscall numbers yourself.

Martin B
  • 23,670
  • 6
  • 53
  • 72
  • The answer you linked in the last paragraph describes when you'd want to use the `syscall(int, ...)` wrapper function in C. Not the `syscall` *instruction* to inline a syscall in asm. If you're playing around with toy programs and not linking libc, you usually want to use syscall directly. – Peter Cordes Dec 07 '20 at 13:06
  • @PeterCordes: is there a `syscall` instruction? On older time we used `INT`, later `ENTER`, and now I think just a `JMP` (no real address, selector table of "segment" has the data on which ring and which kernel address to execute) – Giacomo Catenazzi Dec 07 '20 at 13:26
  • @GiacomoCatenazzi: Yes, AMD introduced [`syscall`](https://www.felixcloutier.com/x86/syscall), and reworked it for AMD64. It's the only way to use the 64-bit system-call ABI from user-space on Linux. It's not plausible that `enter` could be used for system calls - it's a slow way to make a stack frame; perhaps you're thinking of `sysenter` (Intel's 32-bit fast-system-call instruction)? See [What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?](https://stackoverflow.com/q/46087730) for the difference and an example of using Linux `write` both ways. – Peter Cordes Dec 07 '20 at 13:33
  • @GiacomoCatenazzi: Re: `jmp` - what? Perhaps you're thinking of 32-bit Windows DLLs that call into 64-bit code with a far jmp or call, instead of having the kernel support a 32-bit ABI natively (like Linux does). That doesn't enter the kernel, though. (I think you *could* configure the GDT with a call gate or something that would make a far `jmp` or `call` enter the kernel, but I don't know of any mainstream x86-64 OS that does that instead of using the much faster `syscall`.) – Peter Cordes Dec 07 '20 at 13:34
  • @PeterCordes The OP links to the man page for the `syscall(2)` wrapper function, so I assume they're asking about that, not the `syscall` instruction. – Martin B Dec 07 '20 at 15:27
  • 1
    @MartinB: Oh, you're right, this is tagged `[x86-64]` but *not* `[assembly]`, and has `syscall(2)` in the title. We get many questions about the `syscall` instruction, and the OP's first link was about assembly language. In the tags I follow I've basically never seen one like this, and I skimmed too quickly to notice I was making a wrong assumption >. – Peter Cordes Dec 07 '20 at 15:38
  • 1
    Since you're giving a portable answer, you don't want to hard-code the call numbers - they differ between ISAs, even between i386 and amd64. Use `__NR_read` or `SYS_read` after including the appropriate headers (`` or ``). `__NR_read` is 0 on x86-64, but not on i386. – Peter Cordes Dec 07 '20 at 15:40
  • @PeterCordes Thanks, that's a great point -- I've edited the answer accordingly. – Martin B Dec 07 '20 at 21:14