C语言 __属性__((节(“名称”)))用法?

gwo2fgha  于 2023-03-01  发布在  其他
关注(0)|答案(3)|浏览(138)

我已经运行了使用__attribute__((section("name")))的代码,我知道对于gcc编译器,这允许您告诉链接器将创建的对象放在特定的“name”节(在链接器文件中声明“name”绝对地址)。
这样做而不只是使用.data节有什么意义呢?

juud5qan

juud5qan1#

有许多可能的用途。[编辑以添加注解:这只是我自己见过或考虑过的一个例子,而不是一个完整的列表。]
例如,Linux内核将一些代码和数据段标记为仅在内核引导时使用,这些代码和数据段可以在内核运行后丢弃,从而回收空间用于其他用途。
您可以使用它来标记需要在特定处理器变体上打补丁的代码或数据值,例如,带或不带协处理器。
您可以使用它来使内容存在于“特殊”地址空间中,这些地址空间将被烧录到PROM或保存在EEPROM中,而不是保存在普通内存中。
你可以用它来收集代码或数据区,用于初始化和清理,就像C++构造函数和析构函数在程序开始之前和结束时运行一样,或者用于使用更短的寻址模式(我不知道这在ARM上有多大应用,因为我自己没有写过任何ARM代码)。
实际使用取决于链接器脚本。

gg58donl

gg58donl2#

从用例的Angular 来看,.data有很多不同的类型,例如:

  • 特定CPU和/或NUMA节点的本地数据
  • 上下文之间共享的数据(如用户/内核空间,.vdsovsyscall页面,或者,另一个例子,引导加载程序和内核)
  • 只读数据或具有特定访问模式/类型限制的其他数据(例如,可缓存性或缓存驻留-后者可以在某些ARM SoC上指定)
  • 持续“状态转换”的数据(例如休眠映像加载或崩溃内核/快速重启重新初始化)
  • 具有特定生命周期/生命周期的数据(仅在 Boot 或运行期间的特定阶段使用,一次性写入数据)
  • 专用于特定内核子系统或特定内核模块的数据
  • “代码共置”数据(x64中的寻址偏移量为+/-2GB,因此如果您需要RIP-相对寻址,则数据必须在当前执行代码的范围内)
  • 数据Map到一些特定的硬件寄存器空间VA范围

所以最后常常是关于 attributes(这里使用的这个词比__attribute__(...)允许你在gcc源代码中声明的含义更一般。是否需要另一个部分和/或另一个部分是否有用......取决于旁观者的眼睛--也就是系统设计者。
因此,section属性的可用性 * 允许灵活性 *,恕我直言,这是一件好事。

u4vypkhs

u4vypkhs3#

多年以后,我会添加一个具体的细节,因为它值得写下来。
如果您创建了自己的节,则可以自己管理它。特别是,您可以使用预处理器宏将某些数据项插入到特殊节中。如果使用该特殊节的唯一对象是预处理器宏,则您可以以分布式方式创建数据结构。
这意味着你可以写一个像ADD_VAR_TO_SPECIAL_SECTION(...)这样的预处理器宏,然后把一堆不同的值以随机的顺序连接成一个数组(或者只是一大堆,如果它们不是同一类型的话)。
这使你能够在编译时创建一个(随机排序的)数据数组。* 没有初始化,没有注册,没有开销。你只需要编译和链接你的代码,所有不同的源文件中的所有宏都把它们的值添加到一个大数组中。
如何使用它?创建一堆“模块”。在一个临时数组中注册init函数和destroy函数。在启动时处理数组。(如果需要,可以添加某种拓扑排序。)您不需要在任何地方拥有模块的主列表,它会自动构建。**或者,**创建一个宏,将单元测试函数注册到测试套件中。同样,它创建不需要“注册”的自组织列表。

相关问题