7mm Не могли бы вы показать системный вызов для API sendto() и API write() по исходникам glibc? Не выходит проследить путь от вызова API до INLINE_SYSCALL. К сожалению, нужно именно для sendto(), а не для send().
скиньте мне исходник __libc_dlopen_mode, а то чет kernel.org даун фор майнтенс, не могу сорцы скачать... хотел посмотреть, как реализован у них dlopen(NULL, ...)...
Я понял вопрос, действительно - магия Но. Я вот смотрю в исходниках ядра линукса, там send реализован через sendto (см. net/socket.c). Кроме этого, для архитектуры x86_32 интерфейс сокетов реализован через один системный вызов sys_socketcall (см. arch/x86/kernel/syscall_table_32.S и net/socket.c). Для x86_64 есть sys_sendto, однако также нет sys_send. Таким образом, получается, что в glibc для linux будет реализация send либо через sendto (x86_64, что и видно в INLINE_SYSCALL (sendto, ...)), либо через елиный интерфейс сокетов socketcall (x86_32). Как-то так
делаешь прогу где вписываешь свои функции, далее делаешь strace для проги и смотришь лог вызовов системных вызовов (жестоко звучит)
Загадка разгадана! У Posix API write() нет никакого тела в glibc и искать его там бессмысленно. Магии нет никакой, просто разработчики glibc используют хаки (dirty hacks - грязные трюки) при сборке и осложняют этим жизнь другим программистам. Вот полюбуйтесь: (echo '#include <sysdep-cancel.h>'; \ echo 'PSEUDO (__libc_write, write, 3)'; \ echo ' ret'; \ echo 'PSEUDO_END(__libc_write)'; \ echo 'libc_hidden_def (__libc_write)'; \ echo 'weak_alias (__libc_write, __write)'; \ echo 'libc_hidden_weak (__write)'; \ echo 'weak_alias (__libc_write, write)'; \ echo 'libc_hidden_weak (write)'; \ ) | gcc -c "часть сроки пропущена" -o /root/research/glibc/io/write.o - .././scripts/mkinstalldirs /root/research/glibc/io При выполнении скрипта во время сборки налету создаётся файл - единица трансляции, содержащая тело неуловимой API-функции write(): Код (Text): #include <sysdep-cancel.h>; PSEUDO (__libc_write, write, 3); ret; PSEUDO_END(__libc_write); libc_hidden_def (__libc_write); weak_alias (__libc_write, __write); libc_hidden_weak (__write); weak_alias (__libc_write, write); libc_hidden_weak (write); Эта единица трансляции, отсутствующая в glibc, и передаётся gcc на компиляцию. Для x86-32 architecture имеем следующие результаты: 1)API write() -> syscall №4 from API write() body: Код (Text): mov edx, [esp+8+arg_8] mov ecx, [esp+8+arg_4] mov ebx, [esp+8+arg_0] mov eax, 4 call ds:_dl_sysinfo ------//------------//------------------- _dl_sysinfo dd offset _dl_sysinfo_int80 ---------//----------//------------------ _dl_sysinfo_int80 proc near int 80h ; LINUX retn _dl_sysinfo_int80 endp Этот экспериментально полученный листинг подтверждается теоретическими результатами: из /usr/include/asm/unistd_32.h -> #define __NR_write 4 2) POSIX API: socket(), bind(), connect(), listen(), accept(), send(), recv(), sendto(), recvfrom(), sendmsg(), recvmsg() используют один syscall № 102. (из unistd_32.h -> #define __NR_socketcall 102 ) from API sendto() body: Код (Text): mov edx, ebx mov eax, 66h mov ebx, 0Bh lea ecx, [esp+arg_0] call ds:_dl_sysinfo Research Resume: Для архитектуры x86-32 сравниваемые POSIX API write() и sendto() не реализованы через один syscall ядра, а используют различные системные вызовы: write() -> №4 sendto() -> №102. До границы входа в ядро эффективность участков кода данных API приблизительно одинакова. Таким образом схожесть функционального поведения различных API не может выступать в качестве гарантии использования ими одного и того же системного вызова.
Для X86_32 sendto реализован через __NR_socketcall (102, arch/x86/include/asm/unistd_32.h). Кто говорил, что write и sendto это один и тот же системный вызов?! А вот socket, listen, accept, send, recv, recvfrom и пр. будут реализованы через тот же __NR_socketcall. Вы народ-то не путайте, перечитайте внимательнее мой пост #23. Для X86_64 ситуация с socketcall будет другая, там его нет, но есть отдельные номера системных вызовов для перечисленных операций (arch/x86/include/asm/unistd_64.h).
7mm Естественно это не Вы говорили, а другие программисты. Но собственно из-за возникновения путаницы с sendto() и write() и начался этот simple research