天天看點

2——man elf的翻譯——Program header (Phdr)

Program header (Phdr)

    program header 是一個 array of structures,每一個描述了 a segment 或者是系統需要的程式執行的資訊。

    一個 object 檔案的 segment 包含一個或幾個 sections。program header 隻有在 executable 和 shared

    object file 中才有意義。ELF header 中的 e_phentsize 和 e_phnum 說明了一個檔案它自己的 program

    header 的大小。ELF program header 的結構體是 Elf32_Phdr 或者是 Elf64_Phdr,用哪個看結構:

        typedef struct {

           uint32_t   p_type;

           Elf32_Off  p_offset;

           Elf32_Addr p_vaddr;

           Elf32_Addr p_paddr;

           uint32_t   p_filesz;

           uint32_t   p_memsz;

           uint32_t   p_flags;

           uint32_t   p_align;

       } Elf32_Phdr;

       typedef struct {

           uint32_t   p_type;

           uint32_t   p_flags;

           Elf64_Off  p_offset;

           Elf64_Addr p_vaddr;

           Elf64_Addr p_paddr;

           uint64_t   p_filesz;

           uint64_t   p_memsz;

           uint64_t   p_align;

       } Elf64_Phdr;

    兩種結構最大不同就是lies in the location of the p_flags member in the total struct.

    p_type  

            這個成員表面了:這個 array element 描述了這個 segment 是什麼類型,或者如何去

            說明 這個 array element 的資訊。

            PT_NULL        沒有被使用,而且其他的成員的值沒有被定義。這個讓這個 program header

                                    忽略 entries。

            PT_LOAD        這是一個 loadable segment,p_filesz 和 p_memsz 描述它。檔案的大小

                                    are mapped to the memory segment 的開始。(實在是不好翻譯)如果此

                                    segment 的 memory size——p_memsz 比檔案大小 p_filesz 大,the "extra"

                                    bytes are defined to hold the value 0 and to follow the segment's 

                                    initialized area. file size 也許不會比 memory size 大。 program header

                                   中出現的 loadable segment 是按升序排序的,sorted on p_vaddr。

            PT_DYNAMIC    

                                    這種格式代表的是 dynamic linking 資訊。

            PT_INTERP   

                                    The array element specifies the location and size of  a  null-terminated

                                    pathname  to  invoke as an interpreter. (我實在是不知道怎麼翻譯這句話)

                                    這種格式隻有對可執行檔案才有意義(沒準對 share object 也有用)。然而,

                                    在一個檔案種此種格式的段最多出現一次。If it is present, 它一定要在

                                    所有 loadable segment 之前出現。

            PT_NOTE       location of notes(ElfN_Nhdr)

            PT_SHLIB      保留字段但是在語義上還沒有被定義。隻要有這種格式段的程式就不會符合 ABI。

            PT_PHDR       如果存在,表示的是 location 和 program header 的大小,也就是自己的大小,

                                    在記憶體種和在鏡像中都是這樣。此段類型在檔案中不能出現超過一次。此外,也許隻有

                                    在 program header table 是程式在 memory image 一部分的時候才會出現。如果它

                                    存在,它必須先于任何可加載的部分條目。

            PT_LOPROC, PT_HIPROC

                                   [PT_LOPROC, PT_HIPROC]are  reserved  for processor-specific semantics.

            PT_GNU_STACK

                                   linux核心使用的GNU擴充,通過p_flags中的标志去控制的 the state of the stack。

    p_offset

            儲存的是從檔案中的段的開始偏移量。

    p_vaddr    

             和p_offset一樣,不過是在虛拟位址中。

    p_paddr

            和實體位址相關,是為了段的實體位址所保留的。在BSD系統中沒有被使用并且必須是0.

    p_filesz

            段在 file image 中的大小,也許是0.

    p_memsz    

            段在 memory image 中的大小,也許是0.

    p_flags    

           為段使用的按位操作的标志:

            PF_X    可執行的段。

            PF_W    可寫段。

            PF_R    可讀段。

            text segment 一般有 PF_X 和 PX_R 權限。 data segment 一般3種都有。

    p_align    

            段在記憶體和檔案中對齊的值。loadable process segment 為了 p_vaddr 和

            p_offset 一定要有合适的值,modulo 頁大小。0和1代表沒有對齊要求。否則,

            一定是一個正的integral power of two(2的積分幂),p_vaddr should equal

             p_offset, modulo p_align.

繼續閱讀