Dove trovi la tabella syscall per Linux?


13

Vedo un sacco di persone che fanno riferimento online

arch/x86/entry/syscalls/syscall_64.tbl

per la tabella syscall, che funziona benissimo. Ma molti altri fanno riferimento

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

che si trova comunemente nel pacchetto delle intestazioni. Come mai syscall_64.tblspettacoli,

0 common  read      sys_read

La risposta giusta e unistd.hmostra

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

E poi mostra __NR_readcome

#define __NR_read 63
__SYSCALL(__NR_read, sys_read)

Perché è 63, e non 1? Come posso dare un senso al di fuori /include/uapi/asm-generic/unistd.h? /usr/include/asm/C'è ancora dentro

/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          

Qualcuno potrebbe dirmi la differenza tra questi unistdfile. Spiegare come unistd.hfunziona? E qual è il metodo migliore per trovare la tabella syscall?

Risposte:


12

Quando sto indagando su questo genere di cose, trovo utile chiedere direttamente al compilatore (per i dettagli vedere Stampa di macro predefinite standard C / GCC nel terminale ):

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

Questo dimostra che le intestazioni coinvolte (su Debian) sono /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, e /usr/include/x86_64-linux-gnu/bits/syscall.h, e le stampe il numero di chiamata del sistema per read, che è 0 su x86-64.

È possibile trovare i numeri di chiamata del sistema per altre architetture se sono state installate le intestazioni di sistema appropriate (in un ambiente cross-compilatore). Per x86 a 32 bit è abbastanza semplice:

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

che coinvolge /usr/include/asm/unistd_32.htra gli altri file di intestazione e stampa il numero 3.

Quindi, dal punto di vista dello spazio utente, vengono definite le chiamate di sistema x86 a 32 bit asm/unistd_32.h 64 bit asm/unistd_64.h. asm/unistd_x32.hviene utilizzato per l' ABI x32 .

uapi/asm-generic/unistd.h elenca le chiamate di sistema predefinite, che vengono utilizzate su architetture che non dispongono di una tabella di chiamate di sistema specifica dell'architettura.

Nel kernel i riferimenti sono leggermente diversi e sono specifici dell'architettura (di nuovo, per architetture che non usano la tabella di chiamata di sistema generica). È qui che arch/x86/entry/syscalls/syscall_64.tblarrivano file come (e alla fine finiscono per produrre i file di intestazione che vengono utilizzati nello spazio utente, unistd_64.hecc.). Troverai molti più dettagli sulle chiamate di sistema nella coppia di articoli LWN sull'argomento, Anatomia di una chiamata di sistema parte 1 e Anatomia di una chiamata di sistema parte 2 .


La tabella di syscall è stabile tra la versione del kernel Linux e quelle future?
Biswapriyo,

@Biswapriyo lo è, fa parte della stabilità ABI che gli sviluppatori del kernel cercano sempre di preservare. È possibile aggiungere nuove syscall, ma quelle vecchie non cambiano, tranne in un numero molto piccolo di casi estremi (come la tuxsyscall ).
Stephen Kitt,


7

63 è readin arm64, 0 è readinx86_64

I numeri di syscall sono diversi per ogni architettura.

I numeri arm64 per esempio sono definiti in: il include/uapi/asm-generic/unistd.hche mostra che 63, vedi anche: /reverseengineering/16917/arm64-syscalls-table/18834#18834

Come spiegato in quella risposta, penso che includere / uapi / asm-generic / unistd.h sia un tentativo più recente di unificare i numeri di syscall in tutti gli archi.

Ma poiché i numeri di syscall non possono cambiare per non rompere l'API di syscall, gli archi più vecchi prima di quello sforzo di unificazione hanno mantenuto i vecchi numeri.

Questa domanda richiede un modo automatizzato per ottenere l'elenco completo di syscall inclusi i parametri: /programming/6604007/how-can-i-get-a-list-of-linux-system-calls-and- il numero-di-args-che-take-automati

strace codice sorgente

Mi fido di quello strumento e mantengono i loro dati in ordine linux/, ad esempio:

Si noti che l'Aarch64 è l'arcnostico #includedell'arco a 64/syscallent.hcui ho fatto riferimento in precedenza.

Quelle tabelle contengono il numero di argomenti, ma non i tipi di argomenti effettivi, mi chiedo dove straceli codifichi.


3

Questa risposta non toccherà la asm-genericversione di unistd.h, perché nulla la include.1

Come notato in syscalls(2):

In parole povere, il codice appartenente alla chiamata di sistema con il numero __NR_xxx definito in /usr/include/asm/unistd.hpuò essere trovato nel sorgente del kernel Linux nella routine sys_xxx().

Cioè, verranno trovati i numeri di syscall corretti /usr/include/asm/unistd.h. Ora, su un tipico sistema x86, questo includerà semplicemente uno dei asm/unistd_*.hfile a seconda della destinazione.

Sono presenti i numeri di syscall appropriati per un programma a 64 bit asm/unistd_64.he quelli per un programma a 32 bit in asm/unistd_32.h(o quasi equivalente_x32.h variante ). I due sono diversi perché le architetture a 32 e 64 bit sono, in effetti, sistemi operativi completamente diversi. Condividono lo stesso set di syscalls, ma non nello stesso ordine, per vari motivi.

Molti di questi hanno anche involucri in linguaggio C, quindi raramente dovrai usarli syscall(2)direttamente.


1 E perché non so a cosa serva.


0

Per aggiungere tutte le ottime risposte, esiste un'utilità ausyscallche può essere utilizzata per elencare tutte le syscalls e le relative mappature di numeri interi per la particolare architettura.

per esempio:

$ ausyscall --dump
Using x86_64 syscall table:
0   read
1   write
2   open
3   close
4   stat
...
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.