syscall

Section: System Calls (2)
Updated: 5 février 2023
Index Return to Main Contents
 

NOM

syscall - appel système indirect  

BIBLIOTHÈQUE

Bibliothèque C standard (libc, -lc)  

SYNOPSIS

#include <sys/syscall.h>      /* Définition des constantes SYS_* */
#include <unistd.h>

long syscall(long numéro, ...);

Exigences de macros de test de fonctionnalités pour la glibc (consulter feature_test_macros(7)) :

syscall()

    Depuis la glibc 2.19:
        _DEFAULT_SOURCE
    Avant la glibc 2.19:
        _BSD_SOURCE || _SVID_SOURCE

 

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 d'enveloppe 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).

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 0 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'enveloppe de la glibc (comme par exemple la plupart des appels système), la 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'enveloppe 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 & 0xFFFFFFFF),
        (unsigned int) (offset >> 32),
        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. Cela implique de passer une valeur fantôme dans r1 (le second argument, qui vaut 0). Il faut également veiller à ce que la division respecte les conventions endian (selon l'ABI C de la plateforme).

Des problèmes similaires peuvent survenir sur MIPS avec l'ABI O32, sur PowerPC avec l'ABI 32 bits, et sur Xtensa.

Notez qu'alors que l'ABI parisc C utilise aussi des paires de registres alignés, il utilise une couche shim pour cacher le résultat de l'espace utilisateur.

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).

Cela n'affecte pas les appels système qui séparent et assemblent manuellement les valeurs 64 bits telles que _llseek(2), preadv(2), preadv2(2), pwritev(2) et pwrite2(2). Bienvenue dans le monde fanstastique du bagage historique.  

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 liste 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 (ou les registres) utilisé(s) pour indiquer le numéro de l'appel système, et le registre utilisé comme code de retour de l'appel système, et le registre utilisé pour signaler une erreur.
Arch/ABI  Instruction  Appel  Ret  Ret Erreur  Notes
    système n°  val  val2   

alpha  callsys  v0  v0  a4 a3  1, 6
arc  trap0  r8  r0  -  
arm/OABI  swi NR  -  r0  -  2
arm/EABI  swi 0x0  r7  r0  r1 -  
arm64  svc #0  w8  x0  x1 -  
blackfin  excpt 0x0  P0  R0  -  
i386  int $0x80  eax  eax  edx -  
ia64  break 0x100000  r15  r8  r9 r10  1, 6
loongarch  syscall 0  a7  a0  -  
m68k  trap #0  d0  d0  -  
microblaze  brki r14,8  r12  r3  -  
mips  syscall  v0  v0  v1 a3  1, 6
nios2  trap  r2  r2  r7  
parisc  ble 0x100(%sr2, %r0)  r20  r28  -  
powerpc  sc  r0  r3  r0  1
powerpc64  sc  r0  r3  cr0.SO  1
riscv  ecall  a7  a0  a1 -  
s390  svc 0  r1  r2  r3 -  3
s390x  svc 0  r1  r2  r3 -  3
superh  trapa #31  r3  r0  r1 -  4, 6
sparc/32  t 0x10  g1  o0  o1 psr/csr  1, 6
sparc/64  t 0x6d  g1  o0  o1 psr/csr  1, 6
tile  swint1  R10  R00  R01  1
x86-64  syscall  rax  rax  rdx -  5
x32  syscall  rax  rax  rdx -  5
xtensa  syscall  a2  a2  -  

Notes :

Sur quelques architectures, un registre est utilisé comme un boléen (0 indiquant aucune erreur et -1 indiquant une erreur) pour signaler que l'appel système a échoué. La valeur de l'erreur actuelle est toujours contenue dans le registre renvoyé. Sur sparc, le bit de transport (carry bit, csr) dans le registre d'état du processeur (psr) est utilisé au lieu d'un registre entier. Sur powerpc64, le bit de débordement (overflow bit) sommaire (SO) dans le champ 0 du registre de condition (cr0) est utilisé.
NR est le numéro de l'appel système.
Pour s390 et s390x, NR (le numéro de l'appel système) peut être passé directement avec svc NR s'il est inférieur à 256.
Sur SuperH, des numéros de capture (« trap ») supplémentaires sont pris en charge pour des raisons historiques mais trapa#31 est l'ABI « unifiée » recommandée.
Les ABI x32 partagent la table syscall avec l'ABI x86-64, mais avec quelques nuances :
De manière à indiquer qu'un appel système est appelé sous une ABI x32, un bit additionnel, _X32_SYSCALL_BIT, est associé par un OU binaire avec le numéro d'appel système. L'ABI utilise un processus qui influe sur le comportement des processus, comme le traitement des signaux ou redémarrage d'un appel système.
Comme x32 a des tailles différentes pour long et les types « pointeur », les dispositions de quelques structures (mais pas toutes ; struct timeval ou struct rlimit sont en 64 bits, par exemple) sont différentes. Pour manipuler cela des appels système supplémentaires sont ajoutés à la table d'appel système, commençant au numéro 512 (sans le _X32_SYSCALL BIT). Par exemple, _NR_ready est défini à 19 pour l'ABI x86-64 et comme _X32_SYSCALL_BIT | 515 pour l'ABI x32. La plupart de ces appels système additionnels sont actuellement identiques aux appels système utilisés pour fournir la compatibilité i386. Cependant, il y a quelques exceptions notables, comme avec prreadv2(2), qui utilisent une entité struct iovec avec des pointeurs et des tailles (« compat_iovec » au niveau du noyau) en 4 bits, mais passe un argument pos 8 bits dans un seul registre et non deux comme il est fait dans toute autre ABI.
Quelques architectures (nommément : Alpha, IA-64, MIPS, SuperH, sparc/32 et sparc/64) utilisent un registre additionnel (« Retval2 » dans la table ci-dessus) pour renvoyer une deuxième valeur de renvoi de l'appel système pipe(2) ; Alpha utilise aussi cette technique pour les appels système getxgid(2), getxuid(2) et getxpid(2) spécifiques à l'architecture. Les autres architectures n'utilisent pas le registre de la seconde valeur renvoyée dans l'interface de l'appel système, même s'il est défini dans l'ABI de System V.

Le second tableau montre les registres utilisés pour passer les paramètres de l'appel système.
Arch/ABIarg1  arg2  arg3  arg4  arg5  arg6  arg7  Notes

alphaa0  a1  a2  a3  a4  a5  -  
arcr0  r1  r2  r3  r4  r5  -  
arm/OABIr0  r1  r2  r3  r4  r5  r6  
arm/EABIr0  r1  r2  r3  r4  r5  r6  
arm64x0  x1  x2  x3  x4  x5  -  
blackfinR0  R1  R2  R3  R4  R5  -  
i386ebx  ecx  edx  esi  edi  ebp  -  
ia64out0  out1  out2  out3  out4  out5  -  
loongarcha0  a1  a2  a3  a4  a5  a6  
m68kd1  d2  d3  d4  d5  a0  -  
microblazer5  r6  r7  r8  r9  r10  -  
mips/o32a0  a1  a2  a3  -  -  -  1
mips/n32, 64a0  a1  a2  a3  a4  a5  -  
nios2r4  r5  r6  r7  r8  r9  -  
pariscr26  r25  r24  r23  r22  r21  -  
powerpcr3  r4  r5  r6  r7  r8  r9  
powerpc64r3  r4  r5  r6  r7  r8  -  
riscva0  a1  a2  a3  a4  a5  -  
s390r2  r3  r4  r5  r6  r7  -  
s390xr2  r3  r4  r5  r6  r7  -  
superhr4  r5  r6  r7  r0  r1  r2  
sparc/32o0  o1  o2  o3  o4  o5  -  
sparc/64o0  o1  o2  o3  o4  o5  -  
tileR00  R01  R02  R03  R04  R05  -  
x86-64rdi  rsi  rdx  r10  r8  r9  -  
x32rdi  rsi  rdx  r10  r8  r9  -  
xtensaa6  a3  a4  a5  a8  a9  -  

Notes :

La convention d'appel système mips/o32 passe les arguments 5 à 8 sur la pile utilisateur.

Notez que ces tableaux ne couvrent pas l'ensemble des conventions d'appel système, certaines architectures peuvent écraser sans distinction d'autres registres non listés ici.  

EXEMPLES

#define _GNU_SOURCE #include <signal.h> #include <sys/syscall.h> #include <unistd.h>

int main(void) {
    pid_t tid;


   tid = syscall(SYS_gettid);
    syscall(SYS_tgkill, getpid(), tid, SIGHUP); }  

VOIR AUSSI

_syscall(2), intro(2), syscalls(2), errno(3), vdso(7)

 

TRADUCTION

La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org> et bubu <bubub@no-log.org>

Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à


 

Index

NOM
BIBLIOTHÈQUE
SYNOPSIS
DESCRIPTION
VALEUR RENVOYÉE
NOTES
Exigences dépendantes de l'architecture
Conventions d'appel par architecture
EXEMPLES
VOIR AUSSI
TRADUCTION

This document was created by man2html, using the manual pages.
Time: 20:34:44 GMT, May 22, 2024