为什么系统加载器在读/执行段加载字符串?

时间:2016-01-20 11:56:10

标签: loader elf

我在ubuntu 15.10 x64

编译了这个简单的程序
char *glob = "hello strings"
void main() {

}

并使用gdb我可以找到“hello strings”位于

使用.text部分读取/执行段。

我已经知道ELF头中包含的一些字符串位于代码段

但为什么用户定义的字符串与代码位于同一段?

我还尝试将字符串的大小放大到0x1000以便检查

是否使用代码段来定位小型字符串是编译器优化,但是

它们也与代码位于同一段。

这对我来说非常有趣,因为直觉上字符串应该是可读的而不是可执行的。

1 个答案:

答案 0 :(得分:1)

默认情况下,Linux链接器会创建两个PT_LOAD段:一个包含.text的只读段和一个包含.data的可写段(初始化数据)。

您的字符串文字位于.rodata部分。

您希望本节中涉及以上两个细分市场中的哪一个?如果它是只读的,则它必须进入包含.text的同一段,并且该段必须是可执行的。如果该部分要进入可写段,它将没有执行权限,但是您可以写入这些字符串,并且当二进制文件的多个实例运行时,它们将不会被共享。

您可以在readelf -l a.out的输出中看到段的分配。

对于旧版本的GCC(4.0之前),您可以看到添加-fwritable-strings会将字符串移动到.data,并移动到不可执行的段中。

Gold链接器支持--rodata标志,它将所有只读非可执行部分移动到单独的PT_LOAD段中。但这增加了动态加载程序必须执行的mmapmprotect调用的数量,因此不是默认值。

相关问题