#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)
системный вызов. Эта проблема не относится к порту новой архитектуры — гарантия «взлома пользовательского пространства» заключается в том, что если он работал вчера, то будет работать и сегодня, но это не говорит о том, что если он работал на существующей архитектуре, его можно перекомпилировать и использовать на какой-то новой архитектуре.