Таблица 64-битных системных вызовов macOS

Я могу найти 64-битную таблицу системных вызовов Linux, но номера вызовов не работают в macOS - я получаю Bus Error: 10 всякий раз, когда я пытаюсь использовать их.

Каковы номера вызовов macOS для таких операций, как sys_write?

2 ответа

Решение

Вам нужно добавить 0x2000000 на номер вызова с помощью syscalls.master файл. Я использую XNU bds/kern/syscalls.master файл Вот функция в syscalls.master файл, который я собираюсь назвать:

4   AUE_NULL    ALL { user_ssize_t write(int fd, user_addr_t cbuf, user_size_t nbyte); } 

С точки зрения регистров для передачи аргументов, это то же самое, что и 64-битный Linux. Аргументы передаются через rdi, rsi, rdx, r10, r8 а также r9 регистры соответственно. write Функция принимает три аргумента, которые описаны в следующей сборке:

mov rax, 0x2000004     ; sys_write call identifier
mov rdi, 1             ; STDOUT file descriptor
mov rsi, myMessage     ; buffer to print
mov rdx, myMessageLen  ; length of buffer
syscall                ; make the system call

Вы можете получить список номеров системных вызовов в режиме пользователя в (/usr/include/)sys/syscall.h. Числа НЕ такие же, как в Linux. Файл автоматически генерируется во время сборки XNU из bsd/kern/syscalls/syscalls.master.

Если вы используете экспорт системного вызова libsystem_kernel, вы можете использовать числа такими, какие они есть. Если вы используете сборку, вы должны добавить 0x2000000, чтобы отметить их для слоя BSD (вместо 0x1000000, что означало бы ловушки Маха, или 0x3000000, что означало бы зависимость от машины).

Чтобы увидеть примеры использования системных вызовов в сборке, вы можете легко разобрать экспортированные оболочки: /usr/lib/system/libsystem_kernel.dylib в x86_64 (или ARM64, использующие jtool из кэша общей библиотеки).

Как уже указывалось, необходимо добавить 0x2000000 к номеру вызова. Объяснение этого магического числа взято из исходников ядра xnu в osfmk / mach / i386 / syscall_sw.h.

Есть классы системных вызовов на OSX. Все системные вызовы входят в ядро ​​с помощью инструкции syscall. В этот момент есть системные вызовы Mach, системные вызовы BSD, NONE, диагностические и машинно-зависимые. Каждый системный вызов помечен перечислением класса, которое сдвинуто влево на 24 бита, SYSCALL_CLASS_SHIFT. Перечисление для системных вызовов BSD: 2, SYSCALL_CLASS_UNIX. Так что магическое число 0x2000000 построено как:

hex(2<<24)
'0x2000000'

Очевидно, вы можете получить это магическое число из исходных кодов ядра, но не из включаемых файлов разработчика. Я думаю, это означает, что Apple действительно хочет, чтобы вы связывались с объектными файлами библиотеки, которые разрешают системный вызов shim, а не используют встроенную процедуру: совместимость объектов, а не совместимость с исходным кодом.

На x86_64 сам системный вызов использует ABI System V (раздел A.2.1), как и Linux, и использует инструкцию syscall. Аргументы передаются в rdi, rsi, rdx, r10, r8 и r9. Номер системного вызова находится в регистре rax.

Другие вопросы по тегам