标签:alt 位置 bsp 向量 lin com 用户态 list idt
uname -a
在本机编译linux 5.0.1 X86-64内核,重新按照64位方式编译,步骤同上一篇博客。
make x86_64_defconfig make menuconfig make #编译内核
vi linux-5.0.1/arch/sh/include/uapi/asm/unistd_64.h
从中可以看到与socket相关的调用号。
1.启用gdb调试系统启动
vi LinuxKernel/menu/Makefile cd menu make rootfs
在图形化界面启动menu后,用终端打开gdb:
查找资料得知,我本机是32位linux,gdb为32位,无法调试64位程序。因此,下面为基于32位linux内核的调试。
在系统启动后,可以看到,内核的初始化完成了以下的函数调用过程:start_kernel > trap_init > idt_setup_traps, 其中start_kernal是内核启动的入口函数。
这一次我们在__sys_listen加入断点
可以看到,当我在Qemu中输入replyhi后,进入断点
在sys_socketcall加入断点,输入了replyhi后,可以看到该方法被调用了4次
Socket本质上是一个glibc中的函数,执行实际上是是调用sys_socketcall()系统调用。sys_socketcall()是几乎所有socket相关函数的入口,即是说,bind,connect等等函数都需要sys_socketcall()作为入口。省略号省略掉的是各种网络编程用得到的函数,全部都在这个系统调用中,socketcall是系统所有socket相关函数打大门。
SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) { unsigned long a[6]; unsigned long a0, a1; int err; unsigned int len; if (call < 1 || call > SYS_SENDMMSG) return -EINVAL; len = nargs[call]; if (len > sizeof(a)) return -EINVAL; /* copy_from_user should be SMP safe. */ if (copy_from_user(a, args, len)) return -EFAULT; audit_socketcall(nargs[call] / sizeof(unsigned long), a); a0 = a[0]; a1 = a[1]; switch (call) { case SYS_SOCKET: err = sys_socket(a0, a1, a[2]); break; case SYS_BIND: err = sys_bind(a0, (struct sockaddr __user *)a1, a[2]); break; //... default: err = -EINVAL; break; } return err; }
标签:alt 位置 bsp 向量 lin com 用户态 list idt
原文地址:https://www.cnblogs.com/tanhao1410/p/12066356.html