BEZEICHNUNG

syscall - indirekter Systemaufruf

BIBLIOTHEK

Standard-C-Bibliothek ( libc, -lc)

ÜBERSICHT

#include <sys/syscall.h>      /* Definition der SYS_*-Konstanten */
#include <unistd.h>
long syscall(long Nummer, …);
Mit Glibc erforderliche Feature-Test-Makros (siehe feature_test_macros(7)):
syscall():
    Seit Glibc 2.19:
        _DEFAULT_SOURCE
    Vor Glibc 2.19:
        _BSD_SOURCE || _SVID_SOURCE

BESCHREIBUNG

syscall() ist eine kleine Bibliotheksfunktion, die den Systemaufruf auslöst, dessen Assemblersprachen-Schnittstelle in Nummer mit den festgelegten Argumenten angegeben wurde. Der Einsatz von syscall() ist beispielsweise hilfreich, wenn ein Systemaufruf ausgelöst werden soll, der in der C-Bibliothek keine Wrapper-Funktion hat.
syscall() speichert CPU-Register vor der Durchführung des Systemaufrufs, stellt die Register nach der Rückkehr von dem Systemaufruf wieder her und speichert alle vom Systemaufruf zurückgelieferten Fehler in errno(3).
Die symbolischen Konstanten für die Systemaufrufnummern können in der Header-Datei <sys/syscall.h> gefunden werden.

RÜCKGABEWERT

Der Rückgabewert wird durch den ausgelösten Systemaufruf definiert. Im Allgemeinen zeigt ein Rückgabewert 0 einen Erfolg an. Ein Rückgabewert -1 zeigt einen Fehler und eine Fehlernummer wird in errno gespeichert.

ANMERKUNGEN

syscall() erschien erstmalig in 4BSD.

Architekturspezifische Anforderungen

Jede Architektur-ABI hat ihre eigenen Anforderungen, wie Argumente für Systemaufrufe an den Kernel übergeben werden. Für Systemaufrufe mit Glibc-Wrapper (beispielsweise die meisten Systemaufrufe) handhabt Glibc die Details des Kopierens der Argumente in die richtigen Register auf eine Weise, die für die Architektur angemessen ist. Wird allerdings syscall() zum Durchführen eines Systemaufrufs verwandt, könnte der Aufrufende die architekturabhängigen Details selber handhaben müssen. Diese Anforderung wird auf bestimmten 32-bit-Architekturen am häufigsten angetroffen.
Auf dem ABI der eingebetteten ARM-Architektur (EABI) muss beispielsweise ein 64-bit-Wert (z.B. long long) an ein gerades Registerpaar ausgerichtet werden. Wird daher syscall() anstelle des von Glibc bereitgestellten Wrappers verwandt, müsste der Systemaufruf readahead(2) in der folgenden Weise auf der ARM-Architektur mit dem ABI im Modus »little endian« ausgelöst werden:

syscall(SYS_readahead, fd, 0,
        (unsigned int) (offset & 0xFFFFFFFF),
        (unsigned int) (offset >> 32),
        count);

Da das Argument »offset« 64 bit beträgt und das erste Argument ( fd) an r0 übergeben wird, muss der aufrufende den 64-bit-Wert manuell zerteilen und ausrichten, so dass er an das Register-Paar r2/r3 übergeben wird. Das bedeutet, dass ein Blindwert in r1 (dem zweiten Argument von 0) eingefügt werden muss. Es muss auch darauf geachtet werden, dass die Zerteilung den Endian-Konventionen folgt (gemäß der C-ABI dieser Plattform).
Ähnliche Probleme können auf MIPS mit dem O32-ABI, auf PowerPC und Parisc mit dem 32-bit-ABI und auf Xtensa auftreten.
Beachten Sie, dass das Parisc-C-ABI zwar auch ausgerichtete Registerpaare verwendet, aber eine Ausgleichs-Schicht verwendet, um das Problem vor dem Anwendungsraum zu verstecken.
Die betroffenen Systemaufrufe sind fadvise64_64(2), ftruncate64(2), posix_fadvise(2), pread64(2), pwrite64(2), readahead(2), sync_file_range(2) und truncate64(2).
Dies betrifft Systemaufrufe, die manuell 64-bit-Werte auseinandernehmen und zusammensetzen, wie _llseek(2), preadv(2), preadv2(2), pwritev(2) und pwritev2(2), nicht. Willkomen in der wundervollen Welt der historischen Altlasten.

Architekturabhängige Aufrufkonventionen

Jede Architektur hat ihre eigene Art, den Kernel aufzurufen und Argumente zu übergeben. Die Details für die verschiedenen Architekturen sind in zwei nachfolgenden Tabellen dargestellt.
Die erste Tabelle führt die Anweisungen auf, die zum Übergang in den Kernelmodus verwandt werden (dies könnte nicht die schnellste oder beste Art zum Übergang in den Kernel sein, bitte schauen Sie auch in vdso(7)), das Register, das zur Angabe der Systemaufrufnummer, das oder die Register, die zur Rückgabe des Ergebnisses des Systemaufrufs und das Register, das zur Signalisierung eines Fehlers verwandt wird.
Arch/ABI Anweisung System Rück Rück Fehler Hinweise
Aufruf # Wert Wert2
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
Nios II trap r2 r2 - r7
PA-RISC 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 - -
Hinweise:
Auf einigen Architekturen wird ein Register als logischer Wert verwandt (0 zeigt an, dass kein Fehler vorliegt und -1 zeigt Fehler an), um mitzuteilen, dass der Systemaufruf fehlschlug. Der tatsächliche Fehlerwert ist weiterhin in dem Rückliefer-Register enthalten. Auf Sparc wird das Zweierübergangsbit ( csr) im Prozessorstatusregister (psr) anstelle eines vollständigen Registers verwandt. Auf PowerPC64 wird das zusammenfassende Überlaufbit ( SO) im Feld 0 des Bedingungsregisters ( cr0) verwandt.
NR ist die Nummer des Systemaufrufs.
Für S390 und S390x kann NR (die Nummer des Systemaufrufs) direkt mit svc NR übergeben werden, falls sie kleiner als 256 ist.
Auf SuperH werden aus historischen Gründen zusätzliche Nummern für Ausnahmebehandlungen unterstützt, aber trapa#31 ist die empfohlene »vereinigte« ABI.
Das x32-ABI nutzt die Systemaufruf-Tabelle der x86-64-ABI mit, es gibt aber kleine Nuancen:
Um anzuzeigen, dass ein Systemaufruf unter der x32-ABI erfolgt, wird ein zusätzliches Bit ( __X32_SYSCALL_BIT) durch ein bitweises ODER mit der Systemaufrufnummer verknüpft. Das von einem Prozess verwandte ABI betrifft einige Prozessverhalten, einschließlich der Signalverarbeitung oder dem Neustarten von Systemaufrufen.
Da x32 andere Größen für long und Zeigertypen hat, ist das Layout einiger Strukturen (aber nicht aller: struct timeval oder struct rlimit sind beispielsweise 64 bit) anders. Um damit umzugehen, werden zusätzliche Systemaufrufe zu der Systemaufruftabelle hinzugefügt, beginnend bei Nummer 512 (ohne das __X32_SYSCALL_BIT). Beispielsweise ist __NR_readv als 19 für das x86-64-ABI und als __X32_SYSCALL_BIT | 515 für das x32-ABI definiert. Die meisten dieser zusätzlichen Systemaufrufe sind tatsächlich zu den Systemaufrufen, die zur Bereitstellung der i386-Kompatibilität verwandt werden, identisch. Es gibt allerdings ein paar bemerkenswerte Ausnahmen, wie preadv2(2), das Einheiten struct iovec mit 4-byte-Zeigern und Größen (»compat_iovec« in der Kernelsprache) verwendet, aber ein 8-byte Argument pos in einem einzelnen Register (und nicht in zweien) übergibt, wie dies in jedem anderen ABI erfolgt.
Einige Architekturen (konkret Alpha, IA-64, MIPS, SuperH, Sparc/32 und Sparc/64) verwenden ein zweites Register (»Rückwert2« in der obigen Tabelle), um einen zweiten Rückgabewert von dem Systemaufruf pipe(2) zurückzugeben. Alpha verwendet diese Technik auch in den architekturspezifischen Systemaufrufen getxpid(2), getxuid(2) und getxgid(2). Andere Architekturen verwenden das zweite Rückgaberegister in der Systemaufrufschnittstelle nicht, selbst wenn es in der System-V-ABI definiert ist.
Die zweite Tabelle zeigt die Register, die zur Übergabe der Systemaufrufargumente verwandt werden.
Arch/ABI Arg1 Arg2 Arg3 Arg4 Arg5 Arg6 Arg7 Hinweise
alpha a0 a1 a2 a3 a4 a5 -
Arc r0 r1 r2 r3 r4 r5 -
Arm/OABI r0 r1 r2 r3 r4 r5 r6
Arm/EABI r0 r1 r2 r3 r4 r5 r6
Arm64 x0 x1 x2 x3 x4 x5 -
Blackfin R0 R1 R2 R3 R4 R5 -
I386 ebx ecx edx esi edi ebp -
Ia64 out0 out1 out2 out3 out4 out5 -
Loongarch a0 a1 a2 a3 a4 a5 a6
M68k d1 d2 d3 d4 d5 a0 -
Microblaze r5 r6 r7 r8 r9 r10 -
MIPS/o32 a0 a1 a2 a3 - - - 1
MIPS/n32,64 a0 a1 a2 a3 a4 a5 -
Nios II r4 r5 r6 r7 r8 r9 -
PA-RISC r26 r25 r24 r23 r22 r21 -
PowerPC r3 r4 r5 r6 r7 r8 r9
PowerPC64 r3 r4 r5 r6 r7 r8 -
riscv a0 a1 a2 a3 a4 a5 -
S390 r2 r3 r4 r5 r6 r7 -
S390x r2 r3 r4 r5 r6 r7 -
SuperH r4 r5 r6 r7 r0 r1 r2
SPARC/32 o0 o1 o2 o3 o4 o5 -
SPARC/64 o0 o1 o2 o3 o4 o5 -
Tile R00 R01 R02 R03 R04 R05 -
X86-64 rdi rsi rdx r10 r8 r9 -
X32 rdi rsi rdx r10 r8 r9 -
Xtensa a6 a3 a4 a5 a8 a9 -
Hinweise:
Die Systemaufrufkonvention von MIPS/o32 übergibt die Argumente 5 bis 8 über den Benutzer-Stack.
Beachten Sie, dass diese Tabellen nicht die gesamte Aufrufkonvention abdecken–einige Architekturen könnten rücksichtslos andere, hier nicht aufgeführte Register belegen.

BEISPIELE

#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); }

SIEHE AUCH

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

ÜBERSETZUNG

Die deutsche Übersetzung dieser Handbuchseite wurde von Helge Kreutzmann <[email protected]> erstellt.
Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.
Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die Mailingliste der Übersetzer