【问题标题】:Is it dangerous to move a variable from .bss to .data?将变量从 .bss 移动到 .data 是否危险?
【发布时间】:2019-01-30 18:52:45
【问题描述】:

我有一些 GCC 想要放入 bss 的全局缓冲区。不幸的是,这将导致 bss 部分超出其分配的大小。我宁愿不为这个乱七八糟的项目更改链接器文件(有很多原因,只是在这里逗我一下)。

将变量从 .bss 移动到 .data 是否危险?

我是这样做的:

uint8_t data_queue[256] __attribute__ ((section(".data_queues")));

然后在链接器文件中,我将.data_queues 添加到.data 部分。我检查了地图文件,缓冲区确实在.data 部分。

我在程序开始时将 data_queue 设置为 0。

如果我这样做,我可能会遇到问题吗?这是一个可怕的想法吗?有没有更好的解决方案?

【问题讨论】:

  • 如果编译器认为这个数据仍然为零,memset 可能会被优化掉的问题。应在启动代码中设置为零(main 之前)。
  • @EugeneSh.,好的,很高兴知道(也很有意义)。我并不真正依赖我认为的元素为零,所以无论如何这可能没什么大不了的。
  • 请记住,您的二进制文件将在大约 256 个字节内增加大小
  • @Eugene Sh 如果它进入.data 部分,这意味着它占用二进制空间(类似于PT_LOAD 属性或elf 中的类似属性,我不记得了),其内容是从二进制复制到内存,不像.bss,它只是在启动时填充零。不同意?最终的二进制文件由最终输出部分(或段)表示,将其放置在 .data 部分
  • 或者... 似乎有一个 GCC 选项告诉它不要使用 BSS! -fno-zero-initialized-in-bssgcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

标签: c gcc linker


【解决方案1】:

创建您自己的部分。不要“移动”它做 .data 段,因为它是一个 UB(你在 .rodata 段中没有相应的数据)。

只需添加到您的链接器脚本:

  .mysection : 
  {
    KEEP(*(.mysection))           
    KEEP(*(.mysection*))         

  } >RAM

uint8_t data_queue[256] __attribute__ ((section(".mysection"), used));

【讨论】:

  • 标准在哪里说它是 UB?另外,为什么要使用KEEP?为什么禁用非引用数据的优化?
  • 这个部分有什么权限?
  • 即使程序中没有引用也会保留数据。 (至少我知道这是 OP 需要的东西)。如果不是,当然可以删除 KEEP
  • @FUNNYDMAN 与RAM 内存区相同
  • 好的,我会这样做,这可能是一个更好的主意。抱歉,UB 是什么?
猜你喜欢
  • 1970-01-01
  • 2013-09-03
  • 2023-04-07
  • 2015-04-19
  • 1970-01-01
  • 2011-01-30
  • 1970-01-01
  • 1970-01-01
  • 2017-08-21
相关资源
最近更新 更多