Où trouvez-vous la table syscall pour Linux?

13

Je vois beaucoup de gens référencer en ligne

arch/x86/entry/syscalls/syscall_64.tbl

pour la table syscall, cela fonctionne bien. Mais beaucoup d'autres font référence

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

qui se trouve généralement dans le paquet d'en-têtes. Comment se fait-il que les syscall_64.tblspectacles,

0 common  read      sys_read

La bonne réponse, et unistd.hmontre,

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

Et puis ça se voit __NR_readcomme

#define __NR_read 63
__SYSCALL(__NR_read, sys_read)

Pourquoi est-ce 63, et non 1? Comment puis-je comprendre le sens de /include/uapi/asm-generic/unistd.h? Il /usr/include/asm/y a toujours

/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          

Quelqu'un pourrait-il me dire la différence entre ces unistdfichiers. Expliquez comment ça unistd.hmarche? Et quelle est la meilleure méthode pour trouver la table syscall?

Evan Carroll
la source

Réponses:

12

Lorsque j'étudie ce genre de chose, je trouve utile de demander directement au compilateur (voir Impression de macros prédéfinies C / GCC standard dans le terminal pour plus de détails):

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

Cela montre que les en- têtes impliqués (sur Debian) sont /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, et /usr/include/x86_64-linux-gnu/bits/syscall.h, et imprime le numéro d'appel du système read, qui est 0 sur x86-64.

Vous pouvez trouver les numéros d'appel système pour d'autres architectures si les en-têtes système appropriés sont installés (dans un environnement de compilation croisée). Pour x86 32 bits, c'est assez simple:

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

qui implique /usr/include/asm/unistd_32.hentre autres des fichiers d'en-tête, et imprime le numéro 3.

Du point de vue de l'espace utilisateur, les appels système x86 32 bits sont définis dans asm/unistd_32.h, les appels système x86 64 bits dans asm/unistd_64.h. asm/unistd_x32.hest utilisé pour l' ABI x32 .

uapi/asm-generic/unistd.h répertorie les appels système par défaut, qui sont utilisés sur les architectures qui n'ont pas de table d'appels système spécifique à l'architecture.

Dans le noyau, les références sont légèrement différentes et sont spécifiques à l'architecture (encore une fois, pour les architectures qui n'utilisent pas la table générique d'appel système). C'est là que des fichiers tels que ceux qui arch/x86/entry/syscalls/syscall_64.tblentrent (et ils finissent par produire les fichiers d'en-tête qui sont utilisés dans l'espace utilisateur, unistd_64.hetc.). Vous trouverez beaucoup plus de détails sur les appels système dans la paire d'articles LWN sur le sujet, Anatomie d'un appel système partie 1 et Anatomie d'un appel système partie 2 .

Stephen Kitt
la source
La table syscall est-elle stable entre la version du noyau Linux et les futures?
Biswapriyo
@Biswapriyo, c'est une partie de la stabilité ABI que les développeurs du noyau essaient toujours de préserver. De nouveaux appels système peuvent être ajoutés, mais les anciens ne changent pas, sauf dans un très petit nombre de cas extrêmes (tels que l' tuxappel système ).
Stephen Kitt
7

63 est readen arm64, 0 est readenx86_64

Les numéros d'appel système sont différents pour chaque architecture.

Les numéros arm64 par exemple sont définis à: include/uapi/asm-generic/unistd.hce qui montre que 63, voir aussi: /reverseengineering/16917/arm64-syscalls-table/18834#18834

Comme expliqué dans cette réponse, je pense que include / uapi / asm-generic / unistd.h est une nouvelle tentative d'unifier les numéros d'appel système sur toutes les arches.

Mais comme les numéros syscall ne peuvent pas changer pour ne pas casser l'API syscall, les anciennes arches avant cet effort d'unification ont conservé les anciens numéros.

Cette question demande un moyen automatisé d'obtenir la liste complète des appels système, y compris les paramètres: /programming/6604007/how-can-i-get-a-list-of-linux-system-calls-and- nombre d'arguments qu'ils prennent automatiquement

strace code source

Je fais confiance à cet outil, et ils gardent leurs données en ordre linux/, par exemple:

Notez que l'aarch64 est l'arn #includeagnostique 64/syscallent.hdont j'ai parlé plus tôt.

Ces tables contiennent le nombre d'arguments, mais pas les types d'arguments réels, je me demande où les stracecode.

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

Cette réponse ne touchera pas à la asm-genericversion de unistd.h, car rien ne l'inclut. 1

Comme indiqué dans syscalls(2):

En gros, le code appartenant à l'appel système avec le numéro __NR_xxx défini dans /usr/include/asm/unistd.hse trouve dans la source du noyau Linux dans la routine sys_xxx().

Autrement dit, les numéros d'appel système corrects se trouvent dans /usr/include/asm/unistd.h. Maintenant, sur un système x86 typique, cela inclura simplement l'un des asm/unistd_*.hfichiers en fonction de la cible.

Les numéros d'appel système appropriés pour un programme 64 bits sont inclus asm/unistd_64.h, et ceux pour un programme 32 bits asm/unistd_32.h(ou la _x32.hvariante presque équivalente ). Les deux sont différents car les architectures 32 et 64 bits sont, en fait, des systèmes d'exploitation complètement différents. Ils partagent le même ensemble d'appels système, mais pas dans le même ordre, pour diverses raisons.

La plupart d'entre eux ont également des wrappers en langage C, donc vous aurez rarement besoin d'utiliser syscall(2)directement.


1 Et parce que je ne sais pas à quoi ça sert.

Renard
la source
0

Pour ajouter toutes les bonnes réponses, il existe un utilitaire ausyscallqui peut être utilisé pour répertorier tous les appels système et leurs mappages entiers pour l'architecture particulière.

par exemple:

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