Где вы найдете таблицу системных вызовов для Linux?


13

Я вижу много людей, ссылающихся на интернет

arch/x86/entry/syscalls/syscall_64.tbl

для таблицы системных вызовов, это работает отлично. Но много других ссылок

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

который обычно находится в пакете заголовков. Как приходят syscall_64.tblшоу,

0 common  read      sys_read

Правильный ответ и unistd.hпоказывает,

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

И тогда это показывает __NR_readкак

#define __NR_read 63
__SYSCALL(__NR_read, sys_read)

Почему это 63, а не 1? Как мне разобраться /include/uapi/asm-generic/unistd.h? Еще /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          

Может ли кто-нибудь сказать мне разницу между этими unistdфайлами. Объясните как unistd.hработает? И какой лучший способ найти таблицу системных вызовов?

Ответы:


12

Когда я исследую подобные вещи, я считаю полезным обратиться напрямую к компилятору (подробности см. В разделе « Печать стандартных предопределенных макросов C / GCC в терминале» ):

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

Это показывает , что заголовки , участвующие (в Debian) являются /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, и /usr/include/x86_64-linux-gnu/bits/syscall.h, и печатает номер системного вызова для read, что 0 на x86-64.

Вы можете найти номера системных вызовов для других архитектур, если у вас установлены соответствующие системные заголовки (в среде кросс-компиляции). Для 32-битной x86 это довольно просто:

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

который включает в себя /usr/include/asm/unistd_32.hсреди других заголовочных файлов, и печатает номер 3.

Таким образом, с точки зрения пользовательского пространства, 32-битные системные вызовы x86 определены в asm/unistd_32.h64-битных системных вызовах x86 asm/unistd_64.h. asm/unistd_x32.hиспользуется для x32 ABI .

uapi/asm-generic/unistd.h перечисляет системные вызовы по умолчанию, которые используются в архитектурах, которые не имеют специфической для архитектуры таблицы системных вызовов.

В ядре ссылки немного отличаются и зависят от архитектуры (опять же, для архитектур, которые не используют общую таблицу системных вызовов). Именно здесь arch/x86/entry/syscalls/syscall_64.tblприходят такие файлы (и в конечном итоге они создают файлы заголовков, которые используются в пространстве пользователя unistd_64.hи т. Д.). Вы найдете гораздо больше подробностей о системных вызовах в паре статей LWN на тему: Анатомия части 1 системного вызова и Анатомия части 2 системного вызова .


Стабильна ли таблица системных вызовов между версией ядра Linux и будущими?
Biswapriyo

@Biswapriyo, это часть стабильности ABI, которую разработчики ядра всегда стараются сохранить. Новые системные вызовы могут быть добавлены, но старые не меняются, за исключением очень небольшого число крайних случаев (например, на системном tuxвызове ).
Стивен Китт


7

63 readв arm64, 0 readвx86_64

Номера системных вызовов различны для каждой архитектуры.

Номера arm64, например, определены в: include/uapi/asm-generic/unistd.hэто показывает, что 63, см. Также: /reverseengineering/16917/arm64-syscalls-table/18834#18834

Как объясняется в этом ответе, я думаю, что include / uapi / asm-generic / unistd.h является более новой попыткой объединения номеров системных вызовов во всех арках.

Но так как числа системных вызовов не могут изменяться, чтобы не нарушать API системных вызовов, старые архивы до этой попытки объединения сохранили старые числа.

Этот вопрос требует автоматического способа получения полного списка системных вызовов, включая параметры: /programming/6604007/how-can-i-get-a-list-of-linux-system-calls-and- число-арг-они-бери автоматизац

strace исходный код

Я доверяю этому инструменту, и они хранят свои данные в чистоте linux/, например:

Заметьте, что aarch64 - это архностный #includeагностик, о 64/syscallent.hкотором я упоминал ранее.

Эти таблицы содержат количество аргументов, но не фактические типы аргументов, мне интересно, где straceих кодирует.


3

Этот ответ не будет касаться asm-genericверсии unistd.h, потому что ничего не включает в себя. 1

Как отмечено в syscalls(2):

Грубо говоря, код, принадлежащий системному вызову с номером __NR_xxx, определенным в, /usr/include/asm/unistd.hможно найти в исходном коде ядра Linux в рутине sys_xxx().

То есть правильные номера системных вызовов будут найдены в /usr/include/asm/unistd.h. Теперь в типичной системе x86 это будет просто включать один из asm/unistd_*.hфайлов в зависимости от цели.

Номера системных вызовов, подходящих для 64-разрядной программы, включены asm/unistd_64.h, а номера для 32-разрядной программы asm/unistd_32.h(или почти эквивалентный _x32.hвариант). Они отличаются друг от друга, потому что 32- и 64-разрядные архитектуры, по сути, совершенно разные операционные системы. Они используют один и тот же набор системных вызовов, но не в одном и том же порядке по разным причинам.

У большинства из них также есть обертки на языке C, поэтому вам редко придется использовать их syscall(2)напрямую.


1 А потому что я не знаю для чего это.


0

Чтобы добавить все отличные ответы, есть утилита, ausyscallкоторая может быть использована для перечисления всех системных вызовов и их целочисленных отображений для конкретной архитектуры.

например:

$ ausyscall --dump
Using x86_64 syscall table:
0   read
1   write
2   open
3   close
4   stat
...
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.