Возвращаемое значение размера или типа системного вызова в Linux
Я понимаю, что при взгляде на код ядра тип возвращаемого значения системного вызова linux равен long int, а его размер 32-bit
,
Можно ли заставить системный вызов linux вернуть 64-bit
значение (типа, скажем, long long int
)?
Я понимаю, что менять размер не имеет смысла, но мне интересно узнать ограничения, если они есть, или это просто вопрос предпочтений.
2 ответа
На x86 возвращаемое значение помещается в eax
зарегистрироваться, поэтому он не может быть больше 32 бит; аналогично, на x86-64 он хранится на rax
(64-битное расширение eax
).
В общем, тенденция, по-видимому, заключается в том, чтобы всегда использовать регистр для возвращаемого значения (что кажется разумным для системных вызовов), поэтому вы ограничены размером "нативного целого" текущей платформы. Если вам нужно вернуть более крупный материал, вам придется прибегнуть к передаче местоположения для вывода через указатель.
Я ограничиваю свое обсуждение x86_64 и i386 в этом ответе:
Системные вызовы объявлены как long
,
64-битное ядро вернет 64-битное значение int обратно в пространство пользователя для системных вызовов. 32-битное ядро вернет 32-битное значение типа int.
Однако предположим, что в 32-битном ядре вы меняете тип возврата системных вызовов на long long; тогда они будут возвращены в%eax и%edx вместе с LSB в%eax и MSB в%edx
Таким образом, ваш гейт вызовов (материал в entry.S) просто должен убедиться, что он не забивает%eax и%edx в инструкциях iret / ret.
Соответствующие функции-оболочки пользовательского пространства, которые выполняют системный вызов с помощью макросов int80 или _syscall() в старых системах или повторно реализуют вызов библиотеки syscall(2) в более новой системе, возвращая тип long long.