赞
踩
摘自:https://zhidao.baidu.com/question/1888780400276062188.html
问题:
经常需要在内核中查找系统调用的定义,比如sys_waitpid,如何快速找到呢?
解决:
1、在老版本内核中,系统调用通常定义为sys_*,所以可以直接通过相关符号查找。
2、但新版本中,系统的调用方式不同,采用了SYSCALL_DEFINE的定义方式,由于各系统调用的实现比较分散,查找起来不算方便。具体查找方法如下:
1)通过sys_的方式找到相应函数的声明,如(include/linux/Syscall.h):
asmlinkage long sys_waitpid(pid_t pid, int __user stat_addr, int options);
确认该声明中的参数个数,这里为3,这继续查找SYSCALL_DEFINE3(waitpid)即可,可以通过正则表达式搜索,也可以直接搜索waitpid的引用,查找SYSCALL_DEFINE3(waitpid)所在的位置,sys_waitpid定义如下(kernel/exit.c):
SYSCALL_DEFINE3(waitpid, pid_t, pid, int __user , stat_addr, int, options)
{
return sys_wait4(pid, stat_addr, options, NULL);
}
此处,有涉及另一个系统调用sys_wait4的定义,需要继续用上述方法查找,该系统调用有4个参数,所以应该查找SYSCALL_DEFINE4(wait4),或者查找wait4的引用,可以找到相应结果(kernel/exit.c)。
SYSCALL_DEFINE4(wait4, pid_t, upid, int __user *, stat_addr,
int, options, struct rusage __user *, ru)
{
…
}
新版本内核中系统调用的定义方式如下(使用了宏定义,定义更简单,但可读性比较差~),供参考:
#define SYSCALL_DEFINE1(name, …) SYSCALL_DEFINEx(1, _##name, VA_ARGS)
#define SYSCALL_DEFINE2(name, …) SYSCALL_DEFINEx(2, _##name, VA_ARGS)
#define SYSCALL_DEFINE3(name, …) SYSCALL_DEFINEx(3, _##name, VA_ARGS)
#define SYSCALL_DEFINE4(name, …) SYSCALL_DEFINEx(4, _##name, VA_ARGS)
#define SYSCALL_DEFINE5(name, …) SYSCALL_DEFINEx(5, _##name, VA_ARGS)
#define SYSCALL_DEFINE6(name, …) SYSCALL_DEFINEx(6, _##name, VA_ARGS)
#define SYSCALL_DEFINEx(x, sname, …)
SYSCALL_METADATA(sname, x, VA_ARGS)
__SYSCALL_DEFINEx(x, sname, VA_ARGS)
#define __PROTECT(…) asmlinkage_protect(VA_ARGS)
#define __SYSCALL_DEFINEx(x, name, …)
asmlinkage long sys##name(__MAP(x,__SC_DECL,VA_ARGS));
static inline long SYSC##name(__MAP(x,__SC_DECL,VA_ARGS));
asmlinkage long SyS##name(__MAP(x,__SC_LONG,VA_ARGS))
{
long ret = SYSC##name(__MAP(x,__SC_CAST,VA_ARGS));
__MAP(x,__SC_TEST,VA_ARGS);
__PROTECT(x, ret,__MAP(x,__SC_ARGS,VA_ARGS));
return ret;
}
SYSCALL_ALIAS(sys##name, SyS##name);
static inline long SYSC##name(__MAP(x,__SC_DECL,VA_ARGS))
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。