套接字系统调用如何到达sys_socketcall
accept函数为例
系统调用中参数从用户态向内核态的传递是通过寄存器完成的,eax表示系统调用,ebx表示第一个参数,ecx表示第二个参数,edx表示第三个参数(主要针对socke.S)
第一层:accept.s文件
(glibc函数库)sysdepsunissysvlinuxaccept.S
#define socket accept //将socket定义为accept
#define _socket _libc_accept
#define NARGS 3 //系统调用的个数
#include < socket.S > //这几个套接字函数的通用实现
第二层:socket.S文件
#include < sysdep.h >
#include < sys/socketcall.h >
#define P(a, b) P2(a, b)
#define P2(a, b) a##b
.text
/* The socket-oriented system calls are handled unusally in Linux.
They are all gated through the single `socketcall' system call number.
`socketcall' takes two arguments: the first is the subcode, specifying
which socket function is being called; and the second is a pointer to
the arguments to the specific function.
The .S files for the other calls just #define socket and #include this. */
.globl P(__,socket)
ENTRY (P(__,socket))
/* Save registers. */
movl %ebx, %edx
movl $SYS_ify(socketcall), %eax/* System call number in %eax. */
//展开$SYS_iff()宏
/* Use ## so `socket' is a separate token that might be #define'd. */
movl $P(SOCKOP_,socket), %ebx/* Subcode is first arg to syscall. */
lea 4(%esp), %ecx/* Address of args is 2nd arg. */
/* Do the system call trap. */
int $0x80
/* Restore registers. */
movl %edx, %ebx
/* %eax is < 0 if there was an error. */
cmpl $-125, %eax
jae syscall_error
/* Successful; return the syscall's value. */
ret
PSEUDO_END (P(__,socket))
c
weak_alias (P(__,socket), socket)
重点看:
movl $SYS_ify(socketcall), %eax /* System call number in %eax. */
展开SYS_iff()宏 (glibc函数库: sysdepsunixsysdep.h)
#ifdef __STDC__
#define SYS_ify(syscall_name) SYS_##syscall_name
#else
#define SYS_ify(syscall_name) SYS_/**/syscall_name
#endif
预处理后为:
movl $SYS_socketcall,%eax
//将系统调用号放入eax中,但是对于网络套接字所有的接口函数而言,他们的共同入口函数是sys_socketcall
//在内核中,总入口函数sys_socketcall的系统调用号为_NR_socketcall,定义在include/linux/unistd.h
#define __NR_socketcall102
//在glib函数库中,有如下的预定义
#define SYS_socketcall _NR_socketcall
所以:
movl $SYS_socketcall,%eax
//将sys_socketcall函数对应的系统调用号赋予eax寄存器,从而使套接字系统调用进入到正常的入口函数中
这样套接字系统调用进入到正确的函数中了。
那么第一个参数是识别系统调用的具体函数的,这个参数在socket.S(glibc库)中:
movl $P(SOCKOP_,socket), %ebx
//预处理后:
movl $SOCKOP_accept,%ebx//这就完成了第一个参数的传递
关于SOCKOP_accept:
查看(glibc库:sysdepsunixsysvlinuxsocketcall.h)
#ifndef _SYS_SOCKETCALL_H
#define _SYS_SOCKETCALL_H 1
/* Define unique numbers for the operations permitted on socket. Linux
uses a single system call for all these functions. The relevant code
file is /usr/include/linux/net.h.
We cannot use a enum here because the values are used in assembler
code. */
#define SOCKOP_socket 1
#define SOCKOP_bind 2
#define SOCKOP_connect 3
#define SOCKOP_listen 4
//可以看到SOCKOP_accept对应的值为5
#define SOCKOP_accept 5
#define SOCKOP_getsockname 6
#define SOCKOP_getpeername 7
#define SOCKOP_socketpair 8
#define SOCKOP_send 9
#define SOCKOP_recv 10
#define SOCKOP_sendto 11
#define SOCKOP_recvfrom 12
#define SOCKOP_shutdown 13
#define SOCKOP_setsockopt 14
#define SOCKOP_getsockopt 15
#define SOCKOP_sendmsg 16
#define SOCKOP_recvmsg 17
#endif /* _SYS_SOCKETCALL_H */
在linux内核(include/linux/net.h):
#ifndef _SYS_SOCKETCALL_H
#define _SYS_SOCKETCALL_H 1
/* Define unique numbers for the operations permitted on socket. Linux
uses a single system call for all these functions. The relevant code
file is /usr/include/linux/net.h.
We cannot use a enum here because the values are used in assembler
code. */
#define SOCKOP_socket 1
#define SOCKOP_bind 2
#define SOCKOP_connect 3
#define SOCKOP_listen 4
//这与glibc库中的SOCKOP_accept对应的值相同
#define SOCKOP_accept 5
#define SOCKOP_getsockname 6
#define SOCKOP_getpeername 7
#define SOCKOP_socketpair 8
#define SOCKOP_send 9
#define SOCKOP_recv 10
#define SOCKOP_sendto 11
#define SOCKOP_recvfrom 12
#define SOCKOP_shutdown 13
#define SOCKOP_setsockopt 14
#define SOCKOP_getsockopt 15
#define SOCKOP_sendmsg 16
#define SOCKOP_recvmsg 17
#endif /* _SYS_SOCKETCALL_H */
第二个参数
在socket.S中:以指针的方式设置了sys_socketcall的第二个参数
lea 4(%esp), %ecx /* Address of args is 2nd arg. */
设置完以上的系统调用号还有参数后进入软中断:int $0x80,进入了内核态进行处理
第三层:entry.S文件
_system_call:
pushl %eax # save orig_eax
SAVE_ALL
movl $-ENOSYS,EAX(%esp)
cmpl $(NR_syscalls),%eax
jae ret_from_sys_call
/*对应上面,未调用软中断之前,eax寄存器中被初始化为系统调用号,即_NR_socketcall,
这个调用号别用于在_sys_call_table数组中进行函数指针的寻址,将对应的函数地址对eax寄存器赋值 */
movl _sys_call_table(,%eax,4),%eax
testl %eax,%eax
je ret_from_sys_call
movl _current,%ebx
andl $~CF_MASK,EFLAGS(%esp) # clear carry - assume no errors
movl $0,errno(%ebx)
movl %db6,%edx
movl %edx,dbgreg6(%ebx) # save current hardware debugging status
testb $0x20,flags(%ebx) # PF_TRACESYS
jne 1f
/*上面给eax复制后,这里进行调用该函数,到这为止,accept系统调用将请求传递给了sys_socketcall,
然后将socket.S中设置的参数传递给sock_accept函数,就完成了应用层接口函数accept到BSD socket层函数的请求传递工作
*/
call *%eax
movl %eax,EAX(%esp) # save the return value
movl errno(%ebx),%edx
negl %edx
je ret_from_sys_call
movl %edx,EAX(%esp)
orl $(CF_MASK),EFLAGS(%esp) # set carry to indicate error
jmp ret_from_sys_call
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
寄存器
+关注
关注
31文章
5620浏览量
130455 -
函数
+关注
关注
3文章
4422浏览量
67873 -
系统
+关注
关注
1文章
1047浏览量
22408
发布评论请先 登录
相关推荐
热点推荐
【MiCOKit试用体验】庆科MiCO系统篇(5)MiCO 套接字
管理协议)、DNS(主域名称系统)、TFTP(通用文件传输协议)等。TCP的通信机制大体可如下图所示UDP的通信机制大体可如下图所示二 MiCOKit套接字在MiCOKit中,有关Socket
发表于 10-24 17:05
命名UNIX域套接字
虽然socketpair函数能创建一对相互连接的套接字,但是每一个套接字都没有名字。这意味着无关进程不能使用它们。如果我们试图绑定同一地址时,该文件已经存在,那么bind请求会失败。当
发表于 09-02 14:45
交换机网络从Soft_AP到Infrastructure后,套接字始终返回无效
与以下代码的客户端连接通过这个实现,TCPPOEN函数返回一个有效的套接字,但是在进入无限循环之后,我们通过在网页中配置网络来配置网络处于基础结构模式。当
发表于 04-24 09:57
STM32例程能否与MFC网络套接字通信?
如题。。想自己写一个PC上的MFC界面。不要求太高的实时性和过大过高的传输数据量,偶尔一次传输几十字节即可,不知道STM32例程能否与MFC网络套接字通信。如果可以就入手一套了,另外,
发表于 08-02 04:36
如何通过socket系统调用创建一个套接字
。服务器端:首先服务器 应用程序通过socket系统调用创建一个套接字,他是系统分配给该服务器进程的类似文件描述符的资源,不能和其他进程分享
发表于 12-24 06:38
RTT网络框架及SAL套接字抽象层介绍
基于自己对各层级的理解,作为划分依据。应用编程、协议栈与网卡驱动首先请允许我简单粗暴地把所有基于协议栈应用接口开发的相关代码,都归属于应用编程下,在带操作系统的情况下,通常协议栈都会提供套接字
发表于 07-28 11:40
netlink 套接字在系统通信中的应用研究
分析了当前普遍应用的几种内核和用户进程的通信方式的不足,详细讨论了linux2.4 以上版本所提供的netlink套接字在内核和用户进程通信中的应用。Linux 作为一种全新的、功能齐备
发表于 08-18 08:47
•17次下载
Windows网络编程的原始套接字详细说明
利用“原始套接字”(Raw Socket),我们可访问位于基层的传输协议。本章专门讲解如何运用这种原始套接字,来模拟 IP的一些实用工具,比如 Tr a c e r o u t e和P
发表于 03-21 08:00
•1次下载
基于AT89C52单片机和LT8030实现套接字规范的计算机通信设计
在网络设置中有HTTP、SOCKET等类型。SOCKET是建立在传输层协议(主要是TCP和UDP)上的一种套接字规范,它定义两台计算机间进行通信的规范(也是一种编程规范)。如果说两台计算机是利用一个
套接字socket包含哪些参数
套接字(Socket)是计算机网络中最基本的通信抽象,它定义了两个进程间通信的端点。在TCP/IP协议栈中,套接字是实现
网络套接字系统调用如何到达sys_socketcall
评论