本来这一节就开始讲open函数的,谁知道内核操作这么骚,一个open函数,搞了那么多个宏定义,虽然能转化出来,但是还是不理解其中深意,等以后理解了之后再回来分析吧。
4.1 open
我们来看看open函数的定义
SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
{
if (force_o_largefile())
flags |= O_LARGEFILE;
return do_sys_open(AT_FDCWD, filename, flags, mode);
}
4.1.1 SYSCALL_DEFINE3
SYSCALL_DEFINE3这是宏定义,我们可以解开一下:
#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
{
if (force_o_largefile())
flags |= O_LARGEFILE;
return do_sys_open(AT_FDCWD, filename, flags, mode);
}
//转化后结果:
SYSCALL_DEFINEx(3, _open, const char __user *, filename, int, flags, umode_t, mode)
{
if (force_o_largefile())
flags |= O_LARGEFILE;
return do_sys_open(AT_FDCWD, filename, flags, mode);
}
4.1.2 SYSCALL_DEFINEx
接下来到SYSCALL_DEFINEx这个宏
#define SYSCALL_DEFINEx(x, sname, ...) \
SYSCALL_METADATA(sname, x, __VA_ARGS__) \
__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
//转化后结果
SYSCALL_METADATA(_open, 3, const char __user *, filename, int, flags, umode_t, mode)
__SYSCALL_DEFINEx(3, _open, const char __user *, filename, int, flags, umode_t, mode)
{
if (force_o_largefile())
flags |= O_LARGEFILE;
return do_sys_open(AT_FDCWD, filename, flags, mode);
}
这个展开好像是两个函数,其实不然,后面的挑战更多
4.1.3 SYSCALL_METADATA
#define SYSCALL_METADATA(sname, nb, ...) \
static const char *types_##sname[] = { \
__MAP(nb,__SC_STR_TDECL,__VA_ARGS__) \
}; \
static const char *args_##sname[] = { \
__MAP(nb,__SC_STR_ADECL,__VA_ARGS__) \
}; \
SYSCALL_TRACE_ENTER_EVENT(sname); \
SYSCALL_TRACE_EXIT_EVENT(sname); \
static struct syscall_metadata __used \
__syscall_meta_##sname = { \
.name = "sys"#sname, \
.syscall_nr = -1, /* Filled in at boot */ \
.nb_args = nb, \
.types = nb ? types_##sname : NULL, \
.args = nb ? args_##sname : NULL, \
.enter_event = &event_enter_##sname, \
.exit_event = &event_exit_##sname, \
.enter_fields = LIST_HEAD_INIT(__syscall_meta_##sname.enter_fields), \
}; \
static struct syscall_metadata __used \
__attribute__((section("__syscalls_metadata"))) \
*__p_syscall_meta_##sname = &__syscall_meta_##sname;
//转化后的结果:
static const char *types__open[] = { \
__MAP(3,__SC_STR_TDECL,__VA_ARGS__) \
}; \
static const char *args__open[] = { \
__MAP(3,__SC_STR_ADECL,__VA_ARGS__) \
}; \
SYSCALL_TRACE_ENTER_EVENT(sname); \
SYSCALL_TRACE_EXIT_EVENT(sname); \
static struct syscall_metadata __used \
__syscall_meta__open = { \
.name = "sys_open", \
.syscall_nr = -1, /* Filled in at boot */ \
.nb_args = 3, \
.types = 3 ? types__open : NULL, \
.args = 3 ? args__open : NULL, \
.enter_event = &event_enter__open, \
.exit_event = &event_exit__open, \
.enter_fields = LIST_HEAD_INIT(__syscall_meta__open.enter_fields), \
}; \
static struct syscall_metadata __used \
__attribute__((section("__syscalls_metadata"))) \
*__p_syscall_meta_open = &__syscall_meta__open;
//这是在填充参数,不知道这些参数有什么用
上面其实好多都没继续展开,我这里继续展开
4.1.4 __MAP
__MAP(3,__SC_STR_TDECL,__VA_ARGS__)
//宏定义
#define __MAP(n,...) __MAP##n(__VA_ARGS__)
//转化结果
__MAP3(__SC_STR_TDECL, const char __user *, filename, int, flags, umode_t, mode)
//宏定义
#define __MAP3(m,t,a,...) m(t,a), __MAP2(m,__VA_ARGS__)
//转化后结果:
__SC_STR_TDECL(const char __user *, filename), __MAP2(__SC_STR_TDECL,__VA_ARGS__)
//宏定义
#define __SC_STR_TDECL(t, a) #t
//转化后结果
const char __user *, __SC_STR_TDECL(int, flags), __MAP1(__SC_STR_TDECL,__VA_ARGS__)
//再次转化
const char __user *, int, umode_t
static const char *types__open[] = { \
__MAP(3,__SC_STR_TDECL,__VA_ARGS__) \
}; \
static const char *args__open[] = { \
__MAP(3,__SC_STR_ADECL,__VA_ARGS__) \
};
//这两个函数再次拆分的结果:
static const char *types__open[] = {
const char __user *, int, umode_t
};
static const char *args__open[] = {
filename, flags, mode
};
4.1.5 SYSCALL_TRACE_ENTER_EVENT
#define SYSCALL_TRACE_ENTER_EVENT(sname) \
static struct syscall_metadata __syscall_meta_##sname; \
static struct trace_event_call __used \
event_enter_##sname = { \
.class = &event_class_syscall_enter, \
{ \
.name = "sys_enter"#sname, \
}, \
.event.funcs = &enter_syscall_print_funcs, \
.data = (void *)&__syscall_meta_##sname,\
.flags = TRACE_EVENT_FL_CAP_ANY, \
}; \
static struct trace_event_call __used \
__attribute__((section("_ftrace_events"))) \
*__event_enter_##sname = &event_enter_##sname;
在填充这个函数,不知道用做什么
4.1.6 SYSCALL_TRACE_EXIT_EVENT
#define SYSCALL_TRACE_EXIT_EVENT(sname) \
static struct syscall_metadata __syscall_meta_##sname; \
static struct trace_event_call __used \
event_exit_##sname = { \
.class = &event_class_syscall_exit, \
{ \
.name = "sys_exit"#sname, \
}, \
.event.funcs = &exit_syscall_print_funcs, \
.data = (void *)&__syscall_meta_##sname,\
.flags = TRACE_EVENT_FL_CAP_ANY, \
}; \
static struct trace_event_call __used \
__attribute__((section("_ftrace_events"))) \
*__event_exit_##sname = &event_exit_##sname;
也是在填充
4.1.7 __SYSCALL_DEFINEx
//太难受了,好多啊
#define __SYSCALL_DEFINEx(x, name, ...) \
asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
__attribute__((alias(__stringify(SyS##name)))); \
static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
asmlinkage long SyS##name(__MAP(x,__SC_LONG,__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; \
} \
static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__))
//转化后结果
asmlinkage long sys_open(const char __user * filename, int flags, umode_t mode) \
__attribute__((alias(__stringify(SyS_open)))); \
static inline long SYSC_open(const char __user * filename, int flags, umode_t mode); \
asmlinkage long SyS_open(filename, flags, mode); \
asmlinkage long SyS_open(filename, flags, mode) \
{ \
long ret = SYSC_open((const char __user * )filename, (int) flags, (umode_t) mode); \
return ret;
}
\
static inline long SYSC_open(const char __user * filename, int flags, umode_t mode)
{
if (force_o_largefile())
flags |= O_LARGEFILE;
return do_sys_open(AT_FDCWD, filename, flags, mode);
}
受不了啊,内核的宏定义就是太恐怖了,想想都头大,不分析把,总感觉不太明白,一分析把就这么恐怖,太难受了,为什么搞这么多宏,我也不清楚,我们只要记住最后调用SYSC_open这个函数执行的。
这篇真是体验感全无。