почему системный вызов open () поддерживается в некоторых системах Linux, а не в других?

#linux-kernel #arm64 #archlinux-arm

#linux-ядро #arm64 #archlinux-arm

Вопрос:

Я встраиваю системные вызовы. Да, я понимаю, что это проблематично, но у меня есть веская причина. Я значительно исправил свою ошибку, и я просто спрашиваю, почему __NR_open исчез в этой системе arm64 Arch Linux?

5.0.1-1-ARCH # 1 SMP Sun Mar 10 15:08:34 MDT 2019 aarch64 GNU/Linux

Опять же, мой код встроен в системные вызовы. Этот встроенный подход работает в другой системе X86_64, и действительно, встроенный mmap () работает в этой системе. Однако при встраивании open() в этот arm64 Arch Linux произошел сбой из-за EFAULT.

Во-первых, чтобы отследить мою ошибку, __NR_open даже не определен в этой среде сборки. Во-вторых, обычный open() вызывает open64(), который выполняет инструкцию svc с x8, установленным на #56, __NR_openat. В-третьих, __NR_open обычно определяется как 5, и это число было изменено на __NR_setxattr. Это объясняет ошибку.

По сути, open() преобразуется в openat() в пользовательской библиотеке в этой системе, а __NR_open системный вызов полностью исчез, замененный новым системным вызовом. Чего я не понимаю, так это того, что __NR_open определен в каноническом исходном коде для arm64, но только не в этой системе Arch Linux arm64.

Мое исправление ошибки простое: вместо этого встроена функция openat(). Но мой вопрос в том, почему это было удалено и почему это не считается нарушенным из Linux POV? Я думаю о том, что Линус сказал, ЧТО МЫ НЕ НАРУШАЕМ ПОЛЬЗОВАТЕЛЬСКОЕ ПРОСТРАНСТВО! и я не думаю об этом из POSIX POV. Действительно, программный интерфейс Linux не распространяется на это удаление, по крайней мере, явно.

Ответ №1:

Файл, на который вы смотрите, arch/arm64/include/asm/unistd32.h — это определения системных вызовов для режима совместимости arm32.

Определения системных вызовов для собственного aarch64 взяты из общей таблицы системных вызовов, включающей/uapi/asm-generic/unistd.h, которая, как вы можете видеть, не определяет __NR_open . Системный вызов не был удален — он никогда не существовал в aarch64.

Причина, которая __NR_open не определена в общей таблице, заключается в том, что openat(2) системный вызов был введен позже и является строгим надмножеством _NR_open функциональности, поэтому нет смысла в портах новой архитектуры (созданных после того, как openat(2) был введен), обеспечивающих этот системный вызов — это избыточно. open() Функция POSIX предоставляется пользовательской библиотекой C, вызываемой в openat(2) системном вызове.

Порты старой архитектуры, которые существовали до openat(2) , такие как x86 и arm32, должны продолжать включаться open(2) , потому что старые двоичные файлы программ / библиотек, безусловно, существуют для тех архитектур, которые вызывают open(2) системный вызов. Эта проблема не относится к порту новой архитектуры — гарантия «взлома пользовательского пространства» заключается в том, что если он работал вчера, то будет работать и сегодня, но это не говорит о том, что если он работал на существующей архитектуре, его можно перекомпилировать и использовать на какой-то новой архитектуре.