首页 > 解决方案 > “address_space()”定义为linux内核中的“稀疏”注解

问题描述

我遇到了一些具有如下定义的宏:

#ifdef __CHECKER__
# define __user     __attribute__((noderef, address_space(1)))

而且我知道这些仅与稀疏(__CHECKER__)一起使用,而 GCC 完全忽略了它们。但是我不明白的是,这address_space()实际上是什么意思?它的可能值是多少?看起来它的唯一文档是大约 16 年前邮件列表中来自 linus 的帖子,上面写着:

当您确实使用解析时,这完全是另一回事。对于“稀疏”,“__iomem”有很多含义:
# define __iomem __attribute__((noderef, address_space(2)))

即“iomem”意味着两个不同的东西:它意味着如果指针被直接取消引用(它是一个“noderef”指针),稀疏应该抱怨,它在“地址空间2”而不是正常的地址空间(0)。

从类似的问答中,发现3表示每 CPU指针,1似乎与从用户空间接收的指针有关。0表示普通指针。

但是address_space(2)实际上是什么意思呢?{0,1,2,3}是唯一可能的值吗

谢谢。

标签: linuxpointerskernelsemantics

解决方案


address_space()并且noderef是属性。可能令人困惑的是它们不是 GCC 属性。它们是稀疏属性,因此它们仅在定义和启用Sparse时才有意义。__CHECKER__Sparse

address_space()属性对标记它的指针设置了特定限制。我的理解是,作为参数的数字是任意选择的,表示指针属于某个类。因此,如果您遵守规则,您应该清楚地将指针注释为属于特定类(例如__useror__iomem等​​),而不是混合来自不同类的指针。使用这些注释Sparse作为静态检查器可以帮助您发现错误使用的情况。

对于address_space(2)aka__iomem我在这里找到了一个很好的描述:在编写设备驱动程序时,__iomem 在 linux 中的用途是什么?Linus 的帖子也是一个很好的描述。

除了{0,1,2,3}之外,还有{4}将指针标记__rcu为一个单独的类。我认为目前没有更多。


推荐阅读