我在linux盒子上的幾個二進制文件中使用了readelf,並在程序頭文件中看到了讓我感到意外的東西。這個例子來自'ld'實用程序,但它也出現在我用gcc編譯的任何東西中。爲什麼程序頭可執行?
PHDR 0x000034 0x08048034 0x08048034 0x00120 0x00120řË爲0x4
這段跨越程序頭的整體。爲什麼被標記爲可執行文件?它不包含機器代碼。但是,爲什麼即使是在頭文件中?我真的不希望它在我的程序圖像中。
我在linux盒子上的幾個二進制文件中使用了readelf,並在程序頭文件中看到了讓我感到意外的東西。這個例子來自'ld'實用程序,但它也出現在我用gcc編譯的任何東西中。爲什麼程序頭可執行?
PHDR 0x000034 0x08048034 0x08048034 0x00120 0x00120řË爲0x4
這段跨越程序頭的整體。爲什麼被標記爲可執行文件?它不包含機器代碼。但是,爲什麼即使是在頭文件中?我真的不希望它在我的程序圖像中。
採取的PHDR指向PHDRS告訴了PHDRS本身應被映射到進程的地址空間的裝載機,以便使它們對程序本身訪問。
這主要用於動態鏈接。
主文件ELF標題在那裏很容易找到其他部分存儲在其中的文件的偏移量。然後,每個子標題描述其部分中的數據。
主要ELF頭看起來像這樣:
/* ELF File Header */
typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf32_Half e_type; /* Object file type */
Elf32_Half e_machine; /* Architecture */
Elf32_Word e_version; /* Object file version */
Elf32_Addr e_entry; /* Entry point virtual address */
Elf32_Off e_phoff; /* Program header table file offset */
Elf32_Off e_shoff; /* Section header table file offset */
Elf32_Word e_flags; /* Processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size in bytes */
Elf32_Half e_phentsize; /* Program header table entry size */
Elf32_Half e_phnum; /* Program header table entry count */
Elf32_Half e_shentsize; /* Section header table entry size */
Elf32_Half e_shnum; /* Section header table entry count */
Elf32_Half e_shstrndx; /* Section header string table index */
} Elf32_Ehdr;
程序頭(一個或多個)是有,因爲它們描述了ELF可執行文件的可執行部分。
程序的下一部分是 ELF程序標題。這些 描述了包含可執行程序代碼 的程序 的部分,以便在加載時映射到程序地址 空間中。
/* Program segment header. */
typedef struct
{
Elf32_Word p_type; /* Segment type */
Elf32_Off p_offset; /* Segment file offset */
Elf32_Addr p_vaddr; /* Segment virtual address */
Elf32_Addr p_paddr; /* Segment physical address */
Elf32_Word p_filesz; /* Segment size in file */
Elf32_Word p_memsz; /* Segment size in memory */
Elf32_Word p_flags; /* Segment flags */
Elf32_Word p_align; /* Segment alignment */
} Elf32_Phdr;
這是從here
我知道他們爲什麼在那裏。我問爲什麼有一個程序頭,告訴我們頭在哪裏。如果你可以閱讀標題,那麼你已經知道在哪裏看。 – eyesathousand 2011-05-31 11:03:16
@eye:有上面提到的程序頭文件,還有主文件ELF頭文件,它包含對所有子頭文件的引用。那是你正在談論的那個嗎? – 2011-05-31 11:06:32
沒有一個程序頭文件定義了一個覆蓋整個程序頭文件的段。 嘗試 readelf -l/bin/ls – eyesathousand 2011-05-31 11:10:03
這是在加載時還是在運行時?我猜如果是在運行時,gcc可能不夠聰明,沒有發現運行時庫加載正在執行。 – eyesathousand 2011-05-31 11:30:16
它也不能解釋爲什麼這個內存應該是可執行的。 – eyesathousand 2011-05-31 11:33:52
程序所鏈接的任何動態庫都可以被動態加載插件的版本替代,因此動態鏈接的程序將始終能夠在執行期間加載共享對象,因此需要存在PHDR。 – 2011-05-31 11:43:35