问题:
经常需要在内核中查找系统调用的定义,比如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__))
阅读(482) | 评论(0) | 转发(0) |