Open main menu

CDOT Wiki β

Changes

Syscalls

3,888 bytes added, 21:38, 25 January 2014
Created page with 'Category:Assembly Language The System call (''syscall'') mechanism is the mechanism used by an application to access kernel services. High-level languages will wrap the sysca…'
[[Category:Assembly Language]]
The System call (''syscall'') mechanism is the mechanism used by an application to access kernel services. High-level languages will wrap the syscall interface in basic wrappers or more advanced mechanisms. For example, in C, the ''write'' syscall can be accessed through the <code>write()</code> wrapper, or through more complex functions such as <code>printf()</code>.

== Syscall Mechanism ==

To invoke a syscall, load syscall number and arguments into the appropriate registers, and then invoke the platform-specific syscall mechanism.

=== x86 32-bit ===

* The syscall number is placed in eax.
* Arguments are placed in edi, esi, edx, ecx with spill over to the stack.
* Return value is in eax.
* The syscall is invoked with <code>int 0x80</code>

=== x86 64-bit ===

* The syscall number is placed in rax.
* Arguments are placed in rdi, rsi, rdx, rcx, r8d, r9d with spill over to the stack.
* Return value is in rax.
* The syscall is invoked with <code>syscall</code>

=== aarch64 ===

* The syscall number is placed in r8.
* Arguments are placed in r0-r7.
* Return value is in r0.
* The syscall is invoked with <code>svc 0</code>

== Syscall information, numbers, and arguments ==

=== Syscall numbers ===

Syscall numbers are defined in <nowiki><asm/unistd.h></nowiki> (<code>/usr/include/asm/unistd.h</code>). If you examine this file, you'll find that it includes different files depending on the platform, because the syscall numbers are platform-specific (on newer platforms, there has been an attempt to use consistent syscall numbers). In this included file, you will find macros for each syscall named <code>__NR_''syscall''</code> which identifies the number for each syscall. For example, aarch64 includes the file <code>/usr/include/asm-generic/unistd.h</code>, which lists this macro for the ''write'' syscall:

#define __NR_write 64

But on x86_64 the macro definition is taken from <code>/usr/include/asm/unistd_64.h</code>:

#define __NR_write 1

=== Syscall arguments and return values ===

The details of each syscall's arguments and return value are listed in <nowiki><unistd.h></nowiki> (<code>/usr/include/unistd.h</code>) in a combination of comments and C extern declarations.For example, for the '''write''' syscall:

/* Write N bytes of BUF to FD. Return the number written, or -1.

This function is a cancellation point and therefore not marked with
__THROW. */
extern ssize_t write (int __fd, const void *__buf, size_t __n) __wur;

So this documents that the ''write'' syscall takes three arguments: the file descriptor, a pointer to the message buffer, and the message size, and returns the number of bytes written or -1 if there was an error.

=== Documentation ===

A list of syscalls can be found in the manpage for <code>syscalls(2)</code> (note: this is different from the manpage for <code>syscall(2)</code> which is a generic syscall wrapper).

Documentation for the C wrappers for most syscalls can be found in the manpage for that wrapper, usually in section 2 of the manual (e.g., <code>write(2)</code>, which is accessed using the command <code>man 2 write</code>).

== Using the syscall macro definitions in asm code ==

The syscall macros can be used in a C program if that program is processed by the C preprocessor (cpp). The extension <code>,S</code> is used to designate an assembler source file that must be processed by cpp.

There are two ways to do this:

1. Invoke cpp explicitly:

cpp foo.S > foo.s
as foo.s -o foo.o
ld foo.o -o foo

2. Use ''gcc'' to invoke the assembler and linker:

gcc foo.S -o foo

{{Admon/important|Initialization Code and Entry Point|When the assembler is invoked through gcc, C initialization code is inserted into the binary, which increases its size. This initialization will look for the entry point <code>main</code> instead of <code>_start</code>.}}