Di mana Anda menemukan tabel syscall untuk Linux?

13

Saya melihat banyak orang referensi online

arch/x86/entry/syscalls/syscall_64.tbl

untuk tabel syscall, itu berfungsi dengan baik. Tapi banyak referensi lain

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

yang biasa ditemukan dalam paket header. Bagaimana bisa syscall_64.tblmenunjukkan,

0 common  read      sys_read

Jawaban yang benar, dan unistd.hmenunjukkan,

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

Dan kemudian ditampilkan __NR_readsebagai

#define __NR_read 63
__SYSCALL(__NR_read, sys_read)

Mengapa itu 63, dan bukan 1? Bagaimana saya masuk akal /include/uapi/asm-generic/unistd.h? Masih di /usr/include/asm/sana

/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          

Bisakah seseorang memberi tahu saya perbedaan antara unistdfile - file ini . Jelaskan cara unistd.hkerjanya? Dan apa metode terbaik untuk menemukan tabel syscall?

Evan Carroll
sumber

Jawaban:

12

Ketika saya menyelidiki hal semacam ini, saya merasa berguna untuk menanyakan kompiler secara langsung (lihat Mencetak makro standar yang sudah ditentukan C / GCC di terminal untuk perincian):

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

Menunjukkan bahwa header yang terlibat (pada Debian) adalah /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, dan /usr/include/x86_64-linux-gnu/bits/syscall.h, dan mencetak jumlah system call untuk read, yang 0 pada x86-64.

Anda dapat menemukan nomor panggilan sistem untuk arsitektur lain jika Anda menginstal header sistem yang sesuai (dalam lingkungan lintas-kompiler). Untuk 32-bit x86 itu cukup mudah:

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

yang melibatkan /usr/include/asm/unistd_32.hantara file header lainnya, dan mencetak angka 3.

Jadi dari perspektif userspace, panggilan sistem x86 32-bit didefinisikan dalam asm/unistd_32.h, panggilan sistem x86 64-bit asm/unistd_64.h. asm/unistd_x32.hdigunakan untuk ABI x32 .

uapi/asm-generic/unistd.h daftar panggilan sistem default, yang digunakan pada arsitektur yang tidak memiliki tabel panggilan sistem arsitektur khusus.

Dalam kernel referensi sedikit berbeda, dan spesifik untuk arsitektur (sekali lagi, untuk arsitektur yang tidak menggunakan tabel panggilan sistem generik). Di sinilah file seperti arch/x86/entry/syscalls/syscall_64.tblmasuk (dan akhirnya menghasilkan file header yang digunakan di ruang pengguna, unistd_64.hdll.). Anda akan menemukan lebih banyak detail tentang pemanggilan sistem pada sepasang artikel LWN tentang topik tersebut, Anatomi pemanggilan sistem bagian 1 dan Anatomi pemanggilan sistem bagian 2 .

Stephen Kitt
sumber
Apakah tabel syscall stabil antara versi kernel Linux dan yang akan datang?
Biswapriyo
@Biswapriyo, itulah bagian dari stabilitas ABI yang selalu dipertahankan oleh para pengembang kernel. Syscalls baru dapat ditambahkan, tapi yang lama tidak berubah, kecuali dalam jumlah yang sangat kecil dari kasus-kasus ekstrim (seperti yang tuxsyscall ).
Stephen Kitt
7

63 ada readdi arm64, 0 ada readdix86_64

Nomor syscall berbeda untuk setiap arsitektur.

Nomor arm64 misalnya didefinisikan di: include/uapi/asm-generic/unistd.hyang menunjukkan bahwa 63, lihat juga: /reverseengineering/16917/arm64-syscalls-table/18834#18834

Seperti dijelaskan dalam jawaban itu, saya pikir itu termasuk / uapi / asm-generic / unistd.h adalah upaya yang lebih baru untuk menyatukan nomor syscall di semua lengkungan.

Tetapi karena nomor syscall tidak dapat berubah untuk tidak merusak API syscall, lengkungan yang lebih tua sebelum upaya unifikasi mempertahankan nomor lama.

Pertanyaan ini meminta cara otomatis untuk mendapatkan daftar syscall lengkap termasuk parameter: /programming/6604007/how-can-i-get-a-list-of-linux-system-calls-and- sejumlah args-mereka-ambil-automati

strace Kode sumber

Saya percaya alat itu, dan mereka menjaga data mereka tetap rapi linux/, misalnya:

Perhatikan bahwa aarch64 #includeadalah agnostik lengkung 64/syscallent.hyang saya sebutkan sebelumnya.

Tabel-tabel itu berisi jumlah argumen, tetapi bukan tipe argumen aktual, saya ingin tahu di mana stracemengkodekannya.

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

Jawaban ini tidak akan menyentuh asm-genericversi unistd.h, karena tidak ada yang memasukkannya. 1

Sebagaimana dicatat dalam syscalls(2):

Secara kasar, kode milik system call dengan nomor __NR_xxx didefinisikan dalam /usr/include/asm/unistd.hdapat ditemukan dalam sumber kernel Linux dalam rutin sys_xxx().

Artinya, nomor syscall yang benar akan ditemukan di /usr/include/asm/unistd.h. Sekarang, pada sistem x86 biasa, ini hanya akan menyertakan salah satu asm/unistd_*.hfile tergantung pada target.

Nomor-nomor syscall yang sesuai untuk program 64-bit ada di dalamnya, dan angka-angka untuk program asm/unistd_64.h32-bit di asm/unistd_32.h(atau _x32.hvarian yang hampir setara ). Keduanya berbeda karena arsitektur 32-dan 64-bit, secara efektif, sistem operasi yang sama sekali berbeda. Mereka berbagi set syscall yang sama, tetapi tidak dalam urutan yang sama, karena berbagai alasan.

Sebagian besar memiliki pembungkus bahasa C juga, jadi Anda jarang perlu menggunakannya syscall(2)secara langsung.


1 Dan karena saya tidak tahu untuk apa itu.

Rubah
sumber
0

Untuk menambahkan semua jawaban yang bagus, ada utilitas ausyscallyang dapat digunakan untuk membuat daftar semua syscalls dan pemetaan bilangan bulat mereka untuk arsitektur tertentu.

misalnya:

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