我在ubuntu 15.10 x64
编译了这个简单的程序char *glob = "hello strings"
void main() {
}
并使用gdb我可以找到“hello strings”位于
使用.text部分读取/执行段。
我已经知道ELF头中包含的一些字符串位于代码段
中但为什么用户定义的字符串与代码位于同一段?
我还尝试将字符串的大小放大到0x1000以便检查
是否使用代码段来定位小型字符串是编译器优化,但是
它们也与代码位于同一段。
这对我来说非常有趣,因为直觉上字符串应该是可读的而不是可执行的。
答案 0 :(得分:1)
默认情况下,Linux链接器会创建两个PT_LOAD
段:一个包含.text
的只读段和一个包含.data
的可写段(初始化数据)。
您的字符串文字位于.rodata
部分。
您希望本节中涉及以上两个细分市场中的哪一个?如果它是只读的,则它必须进入包含.text
的同一段,并且该段必须是可执行的。如果该部分要进入可写段,它将没有执行权限,但是您可以写入这些字符串,并且当二进制文件的多个实例运行时,它们将不会被共享。
您可以在readelf -l a.out
的输出中看到段的分配。
对于旧版本的GCC(4.0之前),您可以看到添加-fwritable-strings
会将字符串移动到.data
,并移动到不可执行的段中。
Gold链接器支持--rodata
标志,它将所有只读非可执行部分移动到单独的PT_LOAD
段中。但这增加了动态加载程序必须执行的mmap
和mprotect
调用的数量,因此不是默认值。