文件系统(四、SYSCALL_DEFINE宏展开)

本来这一节就开始讲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这个函数执行的。

这篇真是体验感全无。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值