Wo finden Sie die Syscall-Tabelle für Linux?

13

Ich sehe viele Leute, die online referenzieren

arch/x86/entry/syscalls/syscall_64.tbl

Für die Syscall-Tabelle funktioniert das einwandfrei. Aber viele andere beziehen sich

/include/uapi/asm-generic/unistd.h

Dies ist häufig im Header-Paket enthalten. Wie kommt es, syscall_64.tblShows,

0 common  read      sys_read

Die richtige Antwort und unistd.hzeigt,

#define __NR_io_setup 0
__SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)

Und dann zeigt es sich __NR_readals

#define __NR_read 63
__SYSCALL(__NR_read, sys_read)

Warum ist das 63 und nicht 1? Wie verstehe ich das /include/uapi/asm-generic/unistd.h? Immer noch /usr/include/asm/drin ist

/usr/include/asm/unistd_x32.h
#define __NR_read (__X32_SYSCALL_BIT + 0)
#define __NR_write (__X32_SYSCALL_BIT + 1)
#define __NR_open (__X32_SYSCALL_BIT + 2)
#define __NR_close (__X32_SYSCALL_BIT + 3)
#define __NR_stat (__X32_SYSCALL_BIT + 4)

/usr/include/asm/unistd_64.h
#define __NR_read 0
#define __NR_write 1
#define __NR_open 2
#define __NR_close 3
#define __NR_stat 4

/usr/include/asm/unistd_32.h
#define __NR_restart_syscall 0
#define __NR_exit 1           
#define __NR_fork 2           
#define __NR_read 3           
#define __NR_write 4          

Könnte mir jemand den Unterschied zwischen diesen unistdDateien sagen . Erklären Sie, wie es unistd.hfunktioniert? Und was ist die beste Methode, um die Syscall-Tabelle zu finden?

Evan Carroll
quelle

Antworten:

12

Wenn ich solche Dinge untersuche, finde ich es nützlich, den Compiler direkt zu fragen ( Einzelheiten finden Sie unter Drucken von vordefinierten Standard-C / GCC-Makros im Terminal ):

printf SYS_read | gcc -include sys/syscall.h -E -

Dies zeigt , dass die Header beteiligt (auf Debian) sind /usr/include/x86_64-linux-gnu/sys/syscall.h, /usr/include/x86_64-linux-gnu/asm/unistd.h, /usr/include/x86_64-linux-gnu/asm/unistd_64.h, und /usr/include/x86_64-linux-gnu/bits/syscall.h, und druckt das System Rufnummer read, die 0 auf x86-64 ist.

Sie finden die Systemrufnummern für andere Architekturen, wenn Sie die entsprechenden Systemheader installiert haben (in einer compilerübergreifenden Umgebung). Für 32-Bit x86 ist es ganz einfach:

printf SYS_read | gcc -include sys/syscall.h -m32 -E -

Dies beinhaltet /usr/include/asm/unistd_32.hunter anderem Header-Dateien und druckt die Nummer 3.

Aus Sicht des Userspace werden also 32-Bit-x86-Systemaufrufe in asm/unistd_32.h64-Bit-x86-Systemaufrufen definiert asm/unistd_64.h. asm/unistd_x32.hwird für den x32 ABI verwendet .

uapi/asm-generic/unistd.h listet die Standardsystemaufrufe auf, die für Architekturen verwendet werden, die keine architekturspezifische Systemaufruftabelle haben.

Im Kernel unterscheiden sich die Referenzen geringfügig und sind architekturspezifisch (wiederum für Architekturen, die die generische Systemaufruftabelle nicht verwenden). Hier arch/x86/entry/syscalls/syscall_64.tblkommen Dateien wie z. B. herein (und letztendlich werden die Header-Dateien erstellt, die im Benutzerbereich unistd_64.husw. verwendet werden). Weitere Informationen zu Systemaufrufen finden Sie in den beiden LWN-Artikeln zum Thema Anatomie eines Systemaufrufs Teil 1 und Anatomie eines Systemaufrufs Teil 2 .

Stephen Kitt
quelle
Ist die Syscall-Tabelle zwischen der Linux-Kernel-Version und zukünftigen Versionen stabil?
Biswapriyo
@Biswapriyo ist es, das ist Teil der ABI-Stabilität, die die Kernel-Entwickler immer zu bewahren versuchen. Neue Syscalls können hinzugefügt werden, alte ändern sich jedoch nur in sehr wenigen extremen Fällen (z. B. beim tuxSyscall ).
Stephen Kitt
7

63 ist readin arm64, 0 ist readinx86_64

Die Syscall-Nummern sind für jede Architektur unterschiedlich.

Die arm64-Nummern sind beispielsweise definiert unter: Dies include/uapi/asm-generic/unistd.hzeigt, dass 63, siehe auch: /reverseengineering/16917/arm64-syscalls-table/18834#18834

Wie in dieser Antwort erläutert, ist include / uapi / asm-generic / unistd.h meiner Meinung nach ein neuerer Versuch, Syscall-Nummern über alle Bögen hinweg zu vereinheitlichen.

Da sich die Syscall-Nummern jedoch nicht ändern können, um die Syscall-API nicht zu beschädigen, haben ältere Bögen vor diesem Vereinigungsaufwand die alten Nummern beibehalten.

In dieser Frage wird nach einer automatisierten Methode zum Abrufen der vollständigen Systemaufrufliste einschließlich der Parameter gefragt: /programming/6604007/how-can-i-get-a-list-of-linux-system-calls-and- Anzahl der Argumente, die sie automatisch nehmen

strace Quellcode

Ich vertraue diesem Tool und sie halten ihre Daten sauber linux/, zB:

Beachten Sie, dass der aarch64 #includeder Arch-Agnostiker ist, auf 64/syscallent.hden ich zuvor Bezug genommen habe.

Diese Tabellen enthalten die Anzahl der Argumente, aber keine tatsächlichen Argumenttypen. Ich frage mich, wo sie stracecodiert sind.

Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功
quelle
3

Diese Antwort wird die asm-genericVersion von nicht berühren unistd.h, da nichts sie enthält. 1

Wie in syscalls(2):

Grob gesagt befindet sich der zum Systemaufruf gehörende Code mit der in definierten Nummer __NR_xxx /usr/include/asm/unistd.hin der Linux- Kernelquelle in der Routine sys_xxx().

Das heißt, die richtigen Syscall-Nummern finden Sie in /usr/include/asm/unistd.h. Auf einem typischen x86-System enthält dies asm/unistd_*.hje nach Ziel einfach eine der Dateien.

Die für ein 64-Bit-Programm geeigneten Syscall-Nummern sind in asm/unistd_64.hund die für ein 32-Bit-Programm in asm/unistd_32.h(oder die nahezu äquivalente _x32.hVariante). Die beiden unterscheiden sich, da die 32- und 64-Bit-Architekturen praktisch völlig unterschiedliche Betriebssysteme sind. Sie verwenden aus verschiedenen Gründen denselben Satz von Systemaufrufen, jedoch nicht in derselben Reihenfolge.

Die meisten davon haben auch Wrapper in C-Sprache, so dass Sie sie selten syscall(2)direkt verwenden müssen.


1 Und weil ich nicht weiß, wofür es ist.

Fuchs
quelle
0

Um all die guten Antworten hinzuzufügen, gibt es ein Dienstprogramm, mit ausyscalldem alle Systemaufrufe und ihre Ganzzahlzuordnungen für die jeweilige Architektur aufgelistet werden können.

z.B:

$ ausyscall --dump
Using x86_64 syscall table:
0   read
1   write
2   open
3   close
4   stat
...
pikaynu
quelle