Nơi nào bạn tìm thấy bảng tòa nhà cho Linux?


13

Tôi thấy rất nhiều người tham khảo trực tuyến

arch/x86/entry/syscalls/syscall_64.tbl

đối với bảng tòa nhà, nó hoạt động tốt. Nhưng rất nhiều người khác tham khảo

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

thường được tìm thấy trong gói tiêu đề. Làm thế nào đến syscall_64.tblchương trình,

0 common  read      sys_read

Câu trả lời đúng, và unistd.hcho thấy,

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

Và sau đó nó hiển thị __NR_readnhư

#define __NR_read 63
__SYSCALL(__NR_read, sys_read)

Tại sao lại là 63 chứ không phải 1? Làm thế nào để tôi có ý nghĩa ra khỏi /include/uapi/asm-generic/unistd.h? Vẫn còn /usr/include/asm/đó

/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          

Ai đó có thể cho tôi biết sự khác biệt giữa các unistdtập tin này . Giải thích cách làm unistd.hviệc? Và phương pháp tốt nhất để tìm bảng tòa nhà là gì?

Câu trả lời:


12

Khi tôi đang điều tra loại điều này, tôi thấy thật hữu ích khi hỏi trực tiếp trình biên dịch (xem In ra các macro được xác định trước C / GCC tiêu chuẩn trong thiết bị đầu cuối để biết chi tiết):

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

Điều này cho thấy các tiêu đề liên quan (trên Debian) là /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, và /usr/include/x86_64-linux-gnu/bits/syscall.h, và in số lượng hệ thống kêu gọi read, đó là 0 trên x86-64.

Bạn có thể tìm thấy các số gọi hệ thống cho các kiến ​​trúc khác nếu bạn đã cài đặt các tiêu đề hệ thống phù hợp (trong môi trường trình biên dịch chéo). Đối với 32-bit x86, điều này khá dễ dàng:

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

liên quan đến /usr/include/asm/unistd_32.hcác tệp tiêu đề khác và in số 3.

Vì vậy, từ góc độ không gian người dùng, các cuộc gọi hệ thống x86 32 bit được xác định trong asm/unistd_32.h, các cuộc gọi hệ thống x86 64 bit asm/unistd_64.h. asm/unistd_x32.hđược sử dụng cho x32 ABI .

uapi/asm-generic/unistd.h liệt kê các cuộc gọi hệ thống mặc định, được sử dụng trên các kiến ​​trúc không có bảng gọi hệ thống dành riêng cho kiến ​​trúc.

Trong nhân, các tham chiếu hơi khác nhau và đặc trưng cho kiến ​​trúc (một lần nữa, đối với các kiến ​​trúc không sử dụng bảng gọi hệ thống chung). Đây là nơi các tệp như arch/x86/entry/syscalls/syscall_64.tblđi vào (và cuối cùng chúng tạo ra các tệp tiêu đề được sử dụng trong không gian người dùng, unistd_64.hv.v.). Bạn sẽ tìm thấy nhiều chi tiết hơn về các cuộc gọi hệ thống trong cặp bài viết của LWN về chủ đề này, Giải phẫu cuộc gọi hệ thống phần 1Giải phẫu cuộc gọi hệ thống phần 2 .


Bảng tòa nhà có ổn định giữa phiên bản nhân Linux và phiên bản tương lai không?
Biswapriyo

@Biswapriyo, đó là một phần của sự ổn định ABI mà các nhà phát triển kernel luôn cố gắng bảo tồn. Syscalls mới có thể được thêm vào, nhưng cái cũ không thay đổi, ngoại trừ một số rất ít các trường hợp nghiêm trọng (chẳng hạn như các tuxsyscall ).
Stephen Kitt


7

63 là readtrong arm64, 0 là readtrongx86_64

Các số tòa nhà là khác nhau cho mỗi kiến ​​trúc.

Ví dụ, số arm64 được xác định tại: include/uapi/asm-generic/unistd.hcho thấy 63, xem thêm: /reverseengineering/16917/arm64-syscalls-table/18834#18834

Như đã giải thích trong câu trả lời đó, tôi nghĩ rằng bao gồm / uapi / asm-generic / unistd.h là một nỗ lực mới hơn trong việc thống nhất các số tòa nhà trên tất cả các vòm.

Nhưng vì các số tòa nhà không thể thay đổi để không phá vỡ API của tòa nhà, nên các vòm cũ hơn trước nỗ lực hợp nhất này đã giữ các số cũ.

Câu hỏi này yêu cầu một cách tự động để có được danh sách tòa nhà đầy đủ bao gồm các tham số: /programming/6604007/how-can-i-get-a-list-of-linux-system-calls-and- số-của-args-họ-mất-automati

strace mã nguồn

Tôi tin tưởng công cụ đó và họ giữ dữ liệu của họ gọn gàng linux/, ví dụ:

Lưu ý rằng aarch64 là một #includethuyết bất khả tri 64/syscallent.hmà tôi đã đề cập trước đó.

Các bảng này chứa số lượng đối số, nhưng không phải là loại đối số thực tế, tôi tự hỏi nơi stracemã hóa chúng.


3

Câu trả lời này sẽ không chạm vào asm-genericphiên bản của unistd.h, bởi vì không có gì bao gồm nó. 1

Như đã lưu ý trong syscalls(2):

Nói một cách đơn giản, mã thuộc về lệnh gọi hệ thống có số __NR_xxx được xác định trong /usr/include/asm/unistd.hcó thể được tìm thấy trong nguồn nhân Linux trong thường trình sys_xxx().

Đó là, số tòa nhà chính xác sẽ được tìm thấy trong /usr/include/asm/unistd.h. Bây giờ, trên một hệ thống x86 điển hình, điều này sẽ chỉ bao gồm một trong các asm/unistd_*.htệp tùy thuộc vào mục tiêu.

Các số tòa nhà thích hợp cho chương trình 64 bit asm/unistd_64.h, và các số cho chương trình 32 bit trong asm/unistd_32.h(hoặc _x32.hbiến thể gần tương đương ). Cả hai đều khác nhau vì kiến ​​trúc 32 và 64 bit, thực sự là các hệ điều hành hoàn toàn khác nhau. Họ chia sẻ cùng một tập hợp các tòa nhà, nhưng không theo cùng một thứ tự, vì nhiều lý do.

Hầu hết trong số này cũng có trình bao bọc ngôn ngữ C, vì vậy hiếm khi bạn cần sử dụng syscall(2)trực tiếp.


1 Và vì tôi không biết nó dùng để làm gì.


0

Để thêm vào tất cả các câu trả lời tuyệt vời, có một tiện ích ausyscallcó thể được sử dụng để liệt kê tất cả các tòa nhà và ánh xạ số nguyên của chúng cho kiến ​​trúc cụ thể.

ví dụ:

$ ausyscall --dump
Using x86_64 syscall table:
0   read
1   write
2   open
3   close
4   stat
...
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.