Linux Kernel代码艺术——系统调用宏定义

我们习惯在SI(Source Insight)中阅读Linux内核,SI会建立符号表数据库,能非常方便地跳转到变量、宏、函数等的定义处。但在处理系统调用的函数时,却会遇到一些麻烦:我们知道系统调用函数名的特点是sys_×××,例如我们想找open函数的内核系统调用代码,在SI提供的符号表中搜索sys_open,能找到函数的声明:

asmlinkage long sys_open(const char __user *filename, int flags, umode_t mode);

原本SI提供从函数名按住Ctrl单击鼠标左键能跳转到定义处的功能,但运用在系统调用函数sys_open上却失败了,这是什么回事呢?

系统调用宏定义展开

经过分析,原来内核中系统调用采用了宏定义,如这里的sys_open就被定义为:

SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)

可以猜测出这个宏定义展开之后就是上面函数声明那样的,难怪SI不能跳转到系统调用的定义处呢!

下面以open系统调用为例分析这个宏是如何展开的:

首先在 include/linux/syscall.h 中有下面这样的宏定义:

#define SYSCALL_DEFINE3(name, ...)                 \
   SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)

针对这个宏定义有几点说明:

  1. 反斜杠\:当宏定义过长需要换行时,在行尾要加上换行标志“\”;
  2. …:省略号代表可变的部分,下面用__VA_AEGS__ 代表省略的变长部分;
  3. ##:分隔连接方式,它的作用是先分隔,然后进行强制连接,例如:
#define VAR(type, name) type name##_##type
VAR(int, var1);
展开之后就是:
int var1_int;

那么:

SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
展开之后是:
SYSCALL_DEFINEx(3, _open, __VA_ARGS__)
这又是一个宏,根据宏定义:
#defi
  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值