NOM¶
syscall - appel système indirect
SYNOPSIS¶
#define _GNU_SOURCE /* Consultez feature_test_macros(7) */
#include <unistd.h>
#include <sys/syscall.h> /* Pour les définitions de SYS_xxx */
int syscall(int numéro, ...);
DESCRIPTION¶
syscall() est une petite fonction de bibliothèque qui invoque
l'appel système dont l'interface en assembleur a le
numéro indiqué avec les arguments donnés.
L'utilisation de
syscall() est pratique, par exemple, pour invoquer un
appel système qui n'a pas de fonction autour de cet appel
système dans la bibliothèque C.
syscall() sauve les registres du processeur avant de faire l'appel
système, restaure les registres au retour de l'appel système et
stocke tous les codes d'erreur renvoyés par l'appel système dans
errno(3) en cas d'erreur.
Les constantes symboliques correspondant aux appels système sont dans le
fichier d'en-tête
<sys/syscall.h>.
VALEUR RENVOYÉE¶
La valeur de retour est définie par l'appel système
invoqué. En général, une valeur de retour nulle indique
une réussite. Une valeur de retour de -1 indique une erreur, et un code
d'erreur est fourni dans
errno.
NOTES¶
syscall() est apparu dans BSD 4.
Exigences dépendantes de l'architecture¶
L'ABI de chaque architecture possède ses propres exigences sur la
façon dont les paramètres des appels système sont
passés au noyau. Pour les appels système qui ont une fonction
d'enrobage de la glibc (comme par exemple la plupart des appels
système), glibc s'occupe des détails pour copier les arguments
dans les bons registres d'une manière adaptée à chaque
architecture. Cependant, en utilisant
syscall() pour effectuer un appel
système, l'appelant peut avoir besoin de gérer certains
détails dépendants de l'architecture ; cette exigence est
en particulier rencontrée sur certaines architectures 32 bits.
Par exemple, pour l'Embedded ABI (EABI) de l'architecture ARM, une valeur
64 bits (c'est-à-dire un
long long) doit être
alignée sur une paire de registres paire. Ainsi, en appelant
syscall() au lieu de la fonction d'enrobage fournie par la glibc,
l'appel système
readahead() devrait être effectué
ainsi sur l'architecture ARM avec l'EABI :
syscall(SYS_readahead, fd, 0,
(unsigned int) (offset >> 32),
(unsigned int) (offset & 0xFFFFFFFF),
count);
Comme le paramètre offset est 64 bits, et le premier argument (
fd) est passé dans
r0, l'appelant doit manuellement
découper et aligner la valeur 64 bits afin de la passer dans la
paire de registres
r2/
r3. Ceci implique de passer une valeur
fantôme dans
r1 (le second argument, qui vaut 0).
Des problèmes similaires peuvent survenir sur MIPS avec l'ABI O32, sur
PowerPC avec l'ABI 32 bits, et sur Xtensa.
Les appels système concernés sont
fadvise64_64(2),
ftruncate64(2),
posix_fadvise(2),
pread64(2),
pwrite64(2),
readahead(2),
sync_file_range(2) et
truncate64(2).
Conventions d'appel par architecture¶
Chaque architecture possède sa façon propre d'invoquer et de
passer des paramètres au noyau. Les détails pour diverses
architectures sont donnés dans les deux tableaux ci-dessous.
Le premier tableau donne l'instruction utilisée pour passer en mode noyau
(qui n'est pas forcément la méthode la meilleure ou la plus
rapide, vous devriez consulter
vdso(7)), le registre utilisé
pour indiquer le numéro de l'appel système, et le registre
utilisé comme code de retour de l'appel système.
arch/ABI |
instruction |
appel syst. |
val. ret. |
Notes |
|
arm/OABI |
swi NR |
- |
a1 |
NR : numéro d'appel syst. |
arm/EABI |
swi 0x0 |
r7 |
r0 |
|
blackfin |
excpt 0x0 |
P0 |
R0 |
|
i386 |
int $0x80 |
eax |
eax |
|
ia64 |
break 0x100000 |
r15 |
r10/r8 |
erreur booléenne/ valeur errno |
parisc |
ble 0x100(%sr2, %r0) |
r20 |
r28 |
|
s390 |
svc 0 |
r1 |
r2 |
Voir ci-dessous. |
s390x |
svc 0 |
r1 |
r2 |
Voir ci-dessous |
sparc/32 |
t 0x10 |
g1 |
o0 |
|
sparc/64 |
t 0x6d |
g1 |
o0 |
|
x86_64 |
syscall |
rax |
rax |
|
Pour s390 and s390x, NR (le numéro de l'appel système) peut
être passé directement avec "svc NR" si NR est
inférieur à 256.
Le second tableau montre les registres utilisés pour passer les
paramètres de l'appel système.
arch/ABI |
par1 |
par2 |
par3 |
par4 |
par5 |
par6 |
par7 |
|
arm/OABI |
a1 |
a2 |
a3 |
a4 |
v1 |
v2 |
v3 |
arm/EABI |
r0 |
r1 |
r2 |
r3 |
r4 |
r5 |
r6 |
blackfin |
R0 |
R1 |
R2 |
R3 |
R4 |
R5 |
- |
i386 |
ebx |
ecx |
edx |
esi |
edi |
ebp |
- |
ia64 |
out0 |
out1 |
out2 |
out3 |
out4 |
out5 |
- |
parisc |
r26 |
r25 |
r24 |
r23 |
r22 |
r21 |
- |
s390 |
r2 |
r3 |
r4 |
r5 |
r6 |
r7 |
- |
s390x |
r2 |
r3 |
r4 |
r5 |
r6 |
r7 |
- |
sparc/32 |
o0 |
o1 |
o2 |
o3 |
o4 |
o5 |
- |
sparc/64 |
o0 |
o1 |
o2 |
o3 |
o4 |
o5 |
- |
x86_64 |
rdi |
rsi |
rdx |
r10 |
r8 |
r9 |
- |
Notez que ces tableaux ne couvrent pas l'ensemble des conventions d'appel
système, certaines architectures peuvent écraser d'autres
registres non listés ici.
EXEMPLE¶
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <signal.h>
int
main(int argc, char *argv[])
{
pid_t tid;
tid = syscall(SYS_gettid);
tid = syscall(SYS_tgkill, getpid(), tid, SIGHUP);
}
VOIR AUSSI¶
_syscall(2),
intro(2),
syscalls(2),
vdso(7)
COLOPHON¶
Cette page fait partie de la publication 3.65 du projet
man-pages Linux.
Une description du projet et des instructions pour signaler des anomalies
peuvent être trouvées à l'adresse
http://www.kernel.org/doc/man-pages/.
TRADUCTION¶
Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a
<
http://po4a.alioth.debian.org/> par l'équipe de traduction
francophone au sein du projet perkamon
<
http://perkamon.alioth.debian.org/>.
Thierry Vignaud (2002), Alain Portal
<
http://manpagesfr.free.fr/> (2006). Julien Cristau et
l'équipe francophone de traduction de Debian (2006-2009).
Veuillez signaler toute erreur de traduction en écrivant à
<debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
paquet
manpages-fr.
Vous pouvez toujours avoir accès à la version anglaise de ce
document en utilisant la commande «
man -L C
<section>
<page_de_man> ».