2016-01-20 41 views
0

我在Ubuntu的15.10 64爲什麼系統加載程序在讀取/執行段加載字符串?

char *glob = "hello strings" 
void main() { 

} 

編譯這個簡單程序,並使用gdb的我能找到的「你好弦」都位於

讀/ .text段執行段。

我已經知道,包含在ELF頭的一些字符串位於代碼段

但爲什麼用戶定義的字符串位於與同一段程序代碼?

我也試圖將字符串的大小放大到0x1000的檢查

無論是編譯器優化,以找到與代碼部分小型字符串,但

它們也位於同一段代碼。

這對我來說很有意思,因爲直觀的字符串應該是可讀的而不是可執行的。

回答

1

缺省情況下,Linux的接頭創建兩個PT_LOAD段:一個只讀之一,含有.text,以及含有.data(初始化的數據)一個可寫的一個。

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

上面兩段中的哪一段您會喜歡本節進入?如果它是隻讀的,那麼它將不得不進入包含.text的同一個段,並且該段必須是可執行的。如果該部分要進入可寫段,則它將不具有執行權限,但是您可以寫入這些字符串,並且在二進制文件的多個實例運行時不會共享它們。

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

使用較舊版本的GCC(4.0之前),您可以看到,添加-fwritable-strings會將該字符串移動到.data以及不可執行的段中。

Gold鏈接器支持--rodata標誌,該標誌將所有隻讀不可執行節移動到單獨的PT_LOAD段中。但是這增加了動態加載器必須執行的mmapmprotect調用的數量,所以不是默認值。