当前位置: 首页 > 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命令相关的功能。

 

 查看它对应的配置:

相关文章:

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

系统调用最大参数是6&#xff0c;由下面这个宏定义&#xff0c;位于文件include\linux\syscalls.h #define SYSCALL_DEFINE_MAXARGS 6 SYSCALL_DEFINE0(fork) fork&#xff1a;系统调用名。 SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr) set_tid_address&#x…...

maven镜像仓库配置(多镜像自动切换)

大家在使用IDEA的时候会遇到这样的一个问题&#xff0c;就是在下载源代码和资源文档的时候&#xff0c;有些镜像仓库里面没有源代码和资源文档&#xff0c;然后会导致下载失败。 这时候就需要多个镜像仓库的地址了。 附上我自己的配置文件&#xff1a; <mirrors><!--…...

ChatGPT在智能监控和安防系统中的应用如何?

ChatGPT在智能监控和安防系统中有着广泛的应用潜力。智能监控和安防系统是利用人工智能和计算机视觉技术来实现对环境的实时监控和安全保障的系统。ChatGPT作为一种通用的预训练语言模型&#xff0c;可以在智能监控和安防系统中发挥以下作用&#xff1a; 1. **智能视频监控**&…...

【Spring Boot Admin】介绍以及使用

介绍 概述 Spring Boot Admin是一个监控工具&#xff0c;旨在以一种漂亮且易于访问的方式可视化Spring Boot Actuators提供的信息。 主要功能点 显示应用程序的监控状态应用程序上下线监控查看 JVM&#xff0c;线程信息可视化的查看日志以及下载日志文件动态切换日志级别Http…...

本地私有仓库部署、docker--harbor私有仓库部署和管理

部署本地私有仓库 拉取镜像 修改daemon.json配置文件 重启docker服务 创建容器 为镜像打标签 上传镜像 查看私有仓库 其他主机拉取私有仓库镜像 Docker--harbor私有仓库 &#xff08;1&#xff09;什么是Harbor Harbor 是 VMware 公司开源的企业级 Docker Registry 项目…...

java根据模板导出word

java根据模板导出word 日常开发中&#xff0c;常常会遇到各种各样的表格进行导出&#xff0c;比较好的办法就是提前弄好word模版&#xff0c;再通过遍历的方式进行导出文档 1、制作word模版 模版编写 内容替换 目标下面模版进行多页展示 将word转换成xml 将xml格式化 再将x…...

spring学习笔记十四

注解开发Bean总结 功能 xml配置注解定义Bean bean标签 id属性class属性 Component ControllerServiceRepositorComponentScan 设置依赖注入 setter注入(set方法) 引用类型/简单类型构造器注入 引用类型和简单类型自动装配 Autowired QualifierValue 配置第三方Bean be…...

【springmvc部分功能源码仿写第一步】实现java对目录下所有文件的遍历

废话不多说&#xff0c;直接上源码&#xff01; public class MiniSpring {public static void main(String[] args) {String path "D:\\ideaProject\\thread";File file new File(path);List<String> list new ArrayList<>();System.out.println(fi…...

SpringBoot中接口幂等性实现方案-自定义注解+Redis+拦截器实现防止订单重复提交

场景 SpringBootRedis自定义注解实现接口防刷(限制不同接口单位时间内最大请求次数)&#xff1a; SpringBootRedis自定义注解实现接口防刷(限制不同接口单位时间内最大请求次数)_redis防刷_霸道流氓气质的博客-CSDN博客 以下接口幂等性的实现方式与上面博客类似&#xff0c;…...

论文解读|用于从RGB-D数据进行3D物体检测的Frustum PointNets

原创 | 文 BFT机器人 01 摘要 论文研究了室内和室外场景中基于RGBD数据的3D目标检测。论文的方法不仅仅依赖于3D方案&#xff0c;而是利用成熟的2D对象检测器和先进的3D深度学习进行对象定位&#xff0c;即使是小对象也能实现高效率和高召回。 直接在原始点云中学习&#xff0…...

3ds Max图文教程: 使用动态工具Mass FX 创建风铃动画

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. 简单的场景设置 步骤 1 打开 3ds Max。 打开 3ds Max 步骤 2 我将向您展示风铃背后的动态 通过简单的场景设置进行模拟。一旦你有了这个想法&#xff0c;你就可以应用这个 技术到复杂的风铃结构。 基…...

抖音矩阵系统源码开发搭建部署分享

一、 功能开发设计 &#xff08;1&#xff09;数据概览&#xff1a;账号&#xff0c;视频top10数据统计 &#xff08;2&#xff09;AI视频创意&#xff1a;原创视频批量剪辑&#xff0c;阶乘算法&#xff0c;去重原理 &#xff08;3&#xff09;同城拓客&#xff1a;线下门店…...

Grafana图形web监控的安装与配置

目录 一、安装并配置 二、Web访问 三、Grafana启用zabbix插件 四、Grafana添加zabbix数据源 五、创建仪表盘 创建监控项完成保存仪表盘 六、查看创建的仪表盘 七、在现有的dashboard&#xff08;仪表盘&#xff09;中添加图形 八、查看最终dashborad&#xff08;仪表盘&#x…...

【机器学习】了解 AUC - ROC 曲线

一、说明 在机器学习中&#xff0c;性能测量是一项基本任务。因此&#xff0c;当涉及到分类问题时&#xff0c;我们可以依靠AUC - ROC曲线。当我们需要检查或可视化多类分类问题的性能时&#xff0c;我们使用AUC&#xff08;曲线下面积&#xff09;ROC&#xff08;接收器工作特…...

Docker 容器生命周期:创建、启动、暂停与停止----从创建到停止多角度分析

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…...

C++STL库中的vector

文章目录 vector的介绍及使用 vector深度剖析及模拟实现 动态二维数组理解 一、vector的介绍及使用 1.vector的介绍 1. vector是表示可变大小数组的序列容器。 2. 就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进…...

PHP 药店管理系统mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP 药品管理系统 是一套完善的web设计系统,系统采用smarty框架进行开发设计&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 PHP 药店管理系统mysql数据库web结构apache计 下载地址…...

【多选框、表格全选】element el-checkbox、el-table

话不多说 先看效果&#xff1a; 多选框&#xff1a; 表格全选&#xff1a; <template><div><div class"titleLabel"><div class"lineStyle"></div>统计部门</div><div style"display: flex"><e…...

【Java】微服务负载均衡算法实现

前言 本篇实现一下分布式中负载均衡的实现策略&#xff0c;以及负载均衡算法是如何实现的。 什么是负载均衡&#xff1f; Java负载均衡是指在多台服务器之间分配负载&#xff0c;以提高服务器的性能和可用性。它通过将请求分发到多台服务器来减少单个服务器的压力&#xff0…...

分类、回归常用损失函数

分类&#xff1a; 交叉熵损失函数&#xff08;Cross-entropy loss function&#xff09; KL散度、交叉熵损失函数、nn.CrossEntropyLoss()_HealthScience的博客-CSDN博客 权重交叉熵损失函数&#xff08;Weighted cross-entropy loss function&#xff09; BCEWithLogitsLo…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

Python 高效图像帧提取与视频编码:实战指南

Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...