【问题标题】:What is the reason for having read-only data defined in .text section?在 .text 部分定义只读数据的原因是什么?
【发布时间】:2018-12-05 03:29:47
【问题描述】:

我正在学习汇编和低级编程本身并阅读book about it。据说我们可以将任何数据放在 elf 文件的 .text 部分中,但当然我们不能改变它,因为页面/段的权限不同.但是那里没有告诉它,它的原因是什么,在 .text 部分中有数据。许多 C++ 程序员也告诉我,g++ 编译器会放

static const char DATA[] = "SOME DATA";

也在 .text 部分内。我想知道,为什么不把这些数据放在 .rodata 部分,目的是什么?而如果使用了.text,那么.rodata中要存储什么?

主要问题是关于长模式下的这种行为。

【问题讨论】:

  • 我试过了,g++ 将DATA 放入.rodata
  • "很多 C++ 程序员也告诉过我" [需要引用]
  • @VictorPolevoy 不,我认为你的标签很好。
  • 另外,如果您正在为可以直接从 ROM 芯片执行代码的系统编写代码,例如在某些 MCU 或更旧的(读取复古)系统中,则不需要复制数据到 RAM 使用它。

标签: c++ assembly


【解决方案1】:

这里说了很多正确的话。我会做一些补充和澄清。

  • 我们可以将常量数据放入.text这一事实并不意味着我们应该。毕竟,指令和数据只是二进制数。
  • 这也不意味着现代编译器(总是)这样做。
  • .rodata.text 和其他部分主要是实现细节。
  • 确实,大块 const 数据通常存储在 .rodata 中。但是,在您的情况下,足够小的 const static 字符串在使用时可能会内联到指令流中。应该放在.rodata 中的字符串本身可能会被优化掉,但它的内容被拆分为一些指令,实际上将存储在.text 中。

【讨论】:

【解决方案2】:

传统上,将只读数据放在文本部分有两个原因:

  • 文本部分不可写,因此内存保护可以捕获对只读数据的意外写入并导致程序崩溃
  • 使用内存管理单元 (MMU),同一进程的多个实例可以共享文本部分的一个副本(因为它保证在程序的所有实例中都是相同的),从而节省内存

在 ELF 目标上,这个方案做了一些修改。只读数据现在放置在新的.rodata 部分中,与.text 部分类似,但它也无法执行,从而防止了某些攻击向量。优势依然存在。

【讨论】:

  • 此外,在为持久性内存芯片 (ROM/...) 构建二进制文件时,“.data”通常位于易失性 DRAM 中,断电时会损坏,并且通常在嵌入式系统上“ .text" 和 ".rodata" 实际上是同一节。在某些平台上,常量也直接在代码之间交错,以允许针对指令指针进行简单的相对寻址,将它们放在“.rodata”中可能会引入额外的指针,如果它与“.text”的相对偏移量不是固定的,有些平台像用于编码的短偏移量。 (加上缓存位置可能会提高性能)。
  • 即“.rodata”与“.text”的问题非常微妙,主要是“因为它在现代平台上在保护方面具有一些次要优势”,但它们非常相似......如果问题是“为什么要阅读-只是,为什么不 .data 并只是初始化它们”,回答这个问题会简单得多,也不那么微妙...... :)
  • 在编译器输出中似乎确实存在r-- 映射以及r-x(文本)和rw-(数据)映射,这些映射来自将代码高尔夫黑客扔到文件中。但字符串文字与main 的映射相同,因此它是可执行的。 (我设置了一个断点并单步执行)。哦,我认为那是另一回事;页面的前 4 个字节是127 '\177' 69 'E' 76 'L' 70 'F',所以它可能是一些元数据。 IDK 如果他们可以将 .rodata 放入该细分市场。
  • 对此更新:ld 的最新版本更改为将 .rodata 链接到它自己的不可执行 ELF 段中,因此 const char code[] = { 0xc3 }; 在转换为函数指针时不再起作用,没有 @ 987654334@。它确实 used 来“正常工作”将机器代码放入 const 数组或字符串文字中。
  • 更新 2:最近的 Linux 内核(5.5 左右)changed the meaning of -z execstack 实际上只使堆栈可执行,而不是 READ_IMPLIES_EXEC。修复大部分Unexpected exec permission from mmap when assembly files included in the project。见How to get c code to execute hex machine code?(包括我对__attribute__((section(".text")))之类的回答)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-26
  • 1970-01-01
  • 2017-04-10
  • 1970-01-01
  • 1970-01-01
  • 2013-06-16
  • 1970-01-01
相关资源
最近更新 更多