【问题标题】:where can I find the reference of gcc extended attribute在哪里可以找到 gcc 扩展属性的参考
【发布时间】:2017-04-20 15:28:06
【问题描述】:

在Linux内核compiler.h中,我找到了__iomem的定义

# define __iomem __attribute__((noderef, address_space(2)))

然后我知道__attribute__(())是GCC的扩展。 但我在 GCC.GNU.Org 中找不到 noderef 或 address_space 的参考

我只发现address_space是manual page of sparse中的扩展属性

【问题讨论】:

  • 那些东西真的要靠操作系统自己来定义。
  • noderef 不是 gcc 属性,这就是为什么您在 gcc 的文档中找不到它...
  • @MarcGlisse,那么,noderef 是什么,我在哪里可以找到文档

标签: c linux gcc kernel


【解决方案1】:

我最近在 Linux 内核源代码中遇到了这个问题,我也很困惑。找到答案并不是最简单的,我提供了这个问题的答案,希望将来有人能看到答案,不会错过 cmets 中的答案。

正如@MarcGlisse 正确指出的那样,您在 GCC 文档中找不到 noderef 或 _address_space_ 因为它们不是 GCC 属性。它们仅对Sparse 有意义。这就是为什么像 __iomem 这样定义的原因

#ifdef __CHECKER__
#define __iomem __attribute__((noderef, address_space(2)))
#else
#define __iomem
#endif

在“正常”编译下,宏被定义但实际上被忽略了。如果启用了检查器,即 Sparse,则会对其进行仔细检查。

@alk 前段时间通过提供指向此LKML article 的链接发表评论,Linus 在其中很好地解释了事情。我在 2006 年第一次看到链接在 Linux Questions thread 中的这篇文章。奇怪的是,我的浏览器出于“安全原因”拒绝打开链接,我不得不在 LKML 档案中找到它。

我希望这有助于了解正在发生的事情。自从您在大约 2.5 年前提出这个问题以来,您可能已经发现情况确实如此。


编辑 答案被否决了。想可能是因为我忽略了为noderef 提供一个含义,所以我现在要提供一个。正如我在答案中提到的,它是 sparse 检查某些东西的信号:指针的 dereference。考虑这个简单的程序:

#include <stdio.h>

#ifdef __CHECKER__
#define __void_region __attribute__((noderef, address_space(2)))
#else
#define __void_region
#endif

int main(void)
{
    int i;
    void * __void_region pMemory = NULL;
    pMemory = &i;

    printf("i is: %d\n", *(int*)pMemory);

    return 0;
}

当使用 sparse 进行检查时,我得到以下信息:

$ sparse foo.c
foo.c:14:9: warning: dereference of noderef expression
foo.c:16:37: warning: dereference of noderef expression

基本上,该定义通知 sparse 以发出取消引用 pMemory 的信号。这是一个无意义的程序,但在内核中,__iomem 永远不应被取消引用,而只能通过适当的 I/O 内核 API 访问。

【讨论】:

  • 我对否决票感到有些困惑。我可以更好地理解为什么吗?这确实回答了这个问题,或者至少回答了我认为的问题,“但我在 GCC.GNU.Org 中找不到 noderef 或 address_space 的引用。”它们不在 GNU 文档中,因为它们不是 GNU GCC 的一部分。如果可以的话,我想让我的答案更好。
【解决方案2】:

"#define iomem __attribute((noderef, address_space(2)))"

浏览互联网我可以找到以下详细信息:

"iomem" 意味着两个不同的东西:它意味着稀疏应该抱怨 如果指针曾经被直接取消引用(它是一个“noderef”指针), 它位于“地址空间 2”中,而不是普通地址空间 (0)。

这个 address_space(2) 或 address_space(0) 表示用于区分内核空间或用户空间或 iomem,如 cpu ring 0 和 ring 3。

更多详情,您可以通过以下链接:-

What is the use of __iomem in linux while writing device drivers?

【讨论】:

  • 我知道__iomem的含义,我的问题是在哪里可以找到noderefaddresss_space()的引用,我查了gcc.gnu.org,我就是找不到。
猜你喜欢
  • 1970-01-01
  • 2021-07-05
  • 2013-04-12
  • 1970-01-01
  • 1970-01-01
  • 2014-01-29
  • 1970-01-01
  • 2010-11-29
  • 2020-05-16
相关资源
最近更新 更多