当前位置: 首页 > news >正文

linux内核系统调用学习5:SYSCALL_DEFINE<0-6>

 系统调用最大参数是6,由下面这个宏定义,位于文件include\linux\syscalls.h

#define SYSCALL_DEFINE_MAXARGS	6
SYSCALL_DEFINE0(fork)

fork:系统调用名。 

SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr)

 set_tid_address:系统调用名

int __user *:第一个参数类型

tidptr:第一个参数。

注意参数类型和参数名之间是用逗号隔开的。后面的2-6也是如此。 

COMPAT_SYSCALL_DEFINE2(stat64, const char __user *, filename,struct compat_stat64 __user *, statbuf)
SYSCALL_DEFINE3(cacheflush,void __user *, addr,unsigned long, bytes,int, cache)
/** The following function implements the controller interface for* the eventpoll file that enables the insertion/removal/change of* file descriptors inside the interest set.*/
SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,struct epoll_event __user *, event)
SYSCALL_DEFINE5(fsconfig,int, fd,unsigned int, cmd,const char __user *, _key,const void __user *, _value,int, aux)
SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,unsigned long, prot, unsigned long, flags,unsigned long, fd, unsigned long, off)

#define SYSCALL_DEFINE0(sname)					\SYSCALL_METADATA(_##sname, 0);				\asmlinkage long sys_##sname(void);			\ALLOW_ERROR_INJECTION(sys_##sname, ERRNO);		\asmlinkage long sys_##sname(void)
#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 __SYSCALL_DEFINEx(x, name, ...)					\__diag_push();							\__diag_ignore(GCC, 8, "-Wattribute-alias",			\"Type aliasing is used to sanitize syscall arguments");\asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))	\__attribute__((alias(__stringify(__se_sys##name))));	\ALLOW_ERROR_INJECTION(sys##name, ERRNO);			\static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__));	\asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__))	\{								\long ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));\__MAP(x,__SC_TEST,__VA_ARGS__);				\__PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__));	\return ret;						\}								\__diag_pop();							\static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))

然后看看__MAP宏系列宏

/** __MAP - apply a macro to syscall arguments* __MAP(n, m, t1, a1, t2, a2, ..., tn, an) will expand to*    m(t1, a1), m(t2, a2), ..., m(tn, an)* The first argument must be equal to the amount of type/name* pairs given.  Note that this list of pairs (i.e. the arguments* of __MAP starting at the third one) is in the same format as* for SYSCALL_DEFINE<n>/COMPAT_SYSCALL_DEFINE<n>*/
#define __MAP0(m,...)
#define __MAP1(m,t,a,...) m(t,a)
#define __MAP2(m,t,a,...) m(t,a), __MAP1(m,__VA_ARGS__)
#define __MAP3(m,t,a,...) m(t,a), __MAP2(m,__VA_ARGS__)
#define __MAP4(m,t,a,...) m(t,a), __MAP3(m,__VA_ARGS__)
#define __MAP5(m,t,a,...) m(t,a), __MAP4(m,__VA_ARGS__)
#define __MAP6(m,t,a,...) m(t,a), __MAP5(m,__VA_ARGS__)
#define __MAP(n,...) __MAP##n(__VA_ARGS__)

__PROTECT宏

#define __PROTECT(...) asmlinkage_protect(__VA_ARGS__)

 asmlinkage_protect宏位于文件include\linux\linkage.h

#ifndef __ASSEMBLY__
#ifndef asmlinkage_protect
# define asmlinkage_protect(n, ret, args...)	do { } while (0)
#endif
#endif

SYSCALL_METADATA宏

这个宏由CONFIG_FTRACE_SYSCALLS决定,定义如下

#ifdef CONFIG_FTRACE_SYSCALLS
#define __SC_STR_ADECL(t, a)	#a
#define __SC_STR_TDECL(t, a)	#textern struct trace_event_class event_class_syscall_enter;
extern struct trace_event_class event_class_syscall_exit;
extern struct trace_event_functions enter_syscall_print_funcs;
extern struct trace_event_functions exit_syscall_print_funcs;#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;#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;#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 inline int is_syscall_trace_event(struct trace_event_call *tp_event)
{return tp_event->class == &event_class_syscall_enter ||tp_event->class == &event_class_syscall_exit;
}#else
#define SYSCALL_METADATA(sname, nb, ...)static inline int is_syscall_trace_event(struct trace_event_call *tp_event)
{return 0;
}
#endif

CONFIG_FTRACE_SYSCALLS从名字上看应该是和trace命令相关的功能。

 

 查看它对应的配置:

http://www.lryc.cn/news/95307.html

相关文章:

  • maven镜像仓库配置(多镜像自动切换)
  • ChatGPT在智能监控和安防系统中的应用如何?
  • 【Spring Boot Admin】介绍以及使用
  • 本地私有仓库部署、docker--harbor私有仓库部署和管理
  • java根据模板导出word
  • spring学习笔记十四
  • 【springmvc部分功能源码仿写第一步】实现java对目录下所有文件的遍历
  • SpringBoot中接口幂等性实现方案-自定义注解+Redis+拦截器实现防止订单重复提交
  • 论文解读|用于从RGB-D数据进行3D物体检测的Frustum PointNets
  • 3ds Max图文教程: 使用动态工具Mass FX 创建风铃动画
  • 抖音矩阵系统源码开发搭建部署分享
  • Grafana图形web监控的安装与配置
  • 【机器学习】了解 AUC - ROC 曲线
  • Docker 容器生命周期:创建、启动、暂停与停止----从创建到停止多角度分析
  • C++STL库中的vector
  • PHP 药店管理系统mysql数据库web结构apache计算机软件工程网页wamp
  • 【多选框、表格全选】element el-checkbox、el-table
  • 【Java】微服务负载均衡算法实现
  • 分类、回归常用损失函数
  • SaaS到底是什么,如何做?这份笔记讲明白了
  • Python 单继承、多继承、@property、异常、文件操作、线程与进程、进程间通信、TCP框架 7.24
  • 【英杰送书第三期】Spring 解决依赖版本不一致报错 | 文末送书
  • ClickHouse修改和删除操作
  • 比selenium体验更好的ui自动化测试工具: cypress介绍
  • Python编译过程和执行原理
  • opencv 图像距离变换 distanceTransform
  • 消息队列——rabbitmq的不同工作模式
  • QT实现用户登录注册功能
  • Docker--harbor私有仓库部署与管理
  • idea复制一份web服务在不同端口启动