ELF(三)程序头表

程序头表

以32位为例;程序头表由几个项组成,其处理方式类似于数组项。

数据结构

/* Program segment header.  */

 

typedef struct

{

 Elf32_Word  p_type;                       /* Segment type */

         描述段的种类,其中段的种类如下:

         PT_NULL表示的段。

         PT_LOAD表示可装载段,在程序执行前从二进制文件映射到内存。

         PT_DYNAMIC表示段包含了用于动态链接器的信息

         PT_INTERP表示当前段指定了可用于动态链接的程序解释器。通常是ld-linux.so

         PT_NOTE指定一个段,其中可能包含专用的编译器信息。

         还有两个是处理器相关,内核不关注。

 Elf32_Off      p_offset;           /* Segment file offset *

         /所述段在文件中的偏移量(从起始位置计算,单位为字节)

 Elf32_Addr   p_vaddr;           /* Segment virtual address */

         给出了段的数据映射到虚拟地址空间中的位置(对于PT_LOAD类型的段)。只支持物理寻址,不支持虚拟寻址的系统,将使用p_paddr保持信息。

 Elf32_Addr   p_paddr;           /* Segment physical address */物理寻址支持

 Elf32_Word  p_filesz;            /* Segment size in file */段在二进制文件中的长度

 Elf32_Word  p_memsz;                  /* Segment size in memory */段在虚拟地址空间中的长度,与文件中的物理的长度差值可通过截断数据或填充0字节来补偿。

 Elf32_Word  p_flags;             /* Segment flags */

         保持了标志信息,定义了该段的访问权限:

         PF_R表示只读

         PF_X表示文件可执行

  Elf32_Word  p_align;             /*Segment alignment */指明了段在内存和二进制文件中的对齐方式,(p_vaddr和p_offet地址必须是模p_align的,既是p_align的倍数)例如p_align的值为0x1000=4096,这意味着段必须对齐到4k页。

} Elf32_Phdr;

截图例子

ELF(三)程序头表_第1张图片

         由上图可以看出该程序头表列出了8个段,这些组成了最终在内存中执行的程序。

其还提供了各段在虚拟地址空间和物理地址空间的位置、大小、标志、访问授权和对齐方面的信息。还指定了一个类型来更精确的描述段。

         PHDR保存程序头表。

         INTERP指定在程序已经从可执行映射到内存之后,必须调用解释器。在这里解释器并不意味着二进制文件的内存必须由另一个程序解释。它指的是这样的一个程序:通过链接其他库,来满足未解决的引用。

         通常/lib/ld-linux-so.2、/lib/ld-linux-ia-64.so.2等库,用于在虚拟地址空间中插入程序运行所需的动态库。对几乎所有的程序来说,可能c标准库都是必须映射的,还需要添加各种哭包括,GTK、数学库、libjpeg等。

         LOAD表示一个从二进制文件映射到虚拟地址空间的段。其中保存了常量数据(如字符串),程序的目标代码等等。

         DYNAMIC段保存了其他动态链接器(即,INTERP中指定的解释器)使用的信息。

         NOTE保存了专有信息。

         虚拟地址空间的各个段,填充了来自ELF文件中特定段的数据。

         readelf输出的第二部分指定了哪些节载入到哪些段。

程序举例

#include
#include

#include
#include
#include
#include




#define elf_file_path           "/home/code/test/main"
#define MA                     1
#define PHDR_SIZE               8
int main(int argc,char** argv) {

#ifdef __x86_64__
#if MA  
   Elf64_Phdr *phdrs = malloc(sizeof (Elf64_Phdr)*PHDR_SIZE);
    if(phdrs == NULL) {
       perror("malloc error");
    }
#else
   Elf64_Phdr phdrs[PHDR_SIZE];
#endif
#else
#if MA  
    Elf32_Phdr*phdrs = malloc(sizeof(Elf32_Phdr)*PHDR_SIZE);
    if(phdrs == NULL) {
       perror("malloc error");
    }
#else
   Elf32_Phdr phdrs[PHDR_SIZE];
#endif
#endif


#ifdef __x86_64__
   memset(phdrs, 0, sizeof (Elf64_Phdr)*PHDR_SIZE);
#else
    memset(phdrs,0, sizeof (Elf32_Phdr)*PHDR_SIZE);
#endif


    int fd = open(elf_file_path, O_RDONLY);
    if(fd < 0) {
       perror("open elf file failed");
    }


#ifdef __x86_64__
   lseek(fd, 64, SEEK_SET);
    intret;
    if((ret = read(fd, phdrs, sizeof (Elf64_Phdr)*PHDR_SIZE)) < 1) {
       perror("read elf file failed");
    }
#else
   lseek(fd, 52, SEEK_SET);
    int ret;
    if((ret = read(fd, phdrs, sizeof (Elf32_Phdr)*PHDR_SIZE)) < 1) {
       perror("read elf file failed");
    }
#endif


    int i= 0;
   printf("Type           Offset      VirtAddr        PhysAddr       FileSiz         MemSiz         Flg             Align\n");
#if 1
    for(; i < PHDR_SIZE; i++) {
#ifdef __x86_64__
#if MA
       Elf64_Phdr *phdr = phdrs++;
#else
       Elf64_Phdr *phdr = &phdrs[i];
#endif 
#else
#if MA
       Elf32_Phdr *phdr = phdrs++;
#else
       Elf32_Phdr *phdr = &phdrs[i];
#endif    
#endif


       switch (phdr->p_type) {
           case PT_NULL:
               printf("%s     ", "NULL");
               break;
           case PT_LOAD:
               printf("%s     ", "LOAD");
               break;
           case PT_DYNAMIC:
               printf("%s     ", "DYNA");
               break;
           case PT_INTERP:
               printf("%s     ", "INTERP");
               break;
           case PT_NOTE:
               printf("%s     ", "NOTE");
               break;
           case PT_SHLIB:
               printf("%s     ", "SHLIB");
               break;
           case PT_PHDR:
               printf("%s     ", "PHDR");
               break;
           case PT_TLS:
               printf("%s     ", "TLS");
               break;
           case PT_NUM:
               printf("%s     ", "NUM");
               break;
           case PT_LOOS:
               printf("%s     ", "LOOS");
               break;
           case PT_GNU_EH_FRAME:
               printf("%s     ", "GNU_EH_FRAME");
               break;
           case PT_GNU_STACK:
               printf("%s      ","GNU_STACK");
               break;
           default:
               printf("%s     ", "OTHER");
               break;
       }
       printf("     0x%-6X     0x%-8X     0x%-8X      0x%-6X       0x%-6X",
               (phdr)->p_offset,
               (phdr)->p_vaddr,
               (phdr)->p_paddr,
               (phdr)->p_filesz,
               (phdr)->p_memsz);




       switch ((phdr)->p_flags) {
           case PF_W:
               printf("       %s", " W ");
               break;
           case PF_R:
               printf("       %s", "R  ");
               break;
           case (PF_W + PF_R):
               printf("       %s", "RW ");
               break;
           case PF_X:
               printf("       %s", "  E");
               break;
           case (PF_X + PF_R):
               printf("       %s", "R E");
               break;
           case (PF_X + PF_W):
               printf("       %s", " WE");
               break;
           case (PF_X + PF_W + PF_R):
               printf("       %s", "RWE");
               break;
           case (PF_MASKOS):
               printf("       %s", "MASKOS");
               break;
           case (PF_MASKPROC):
               printf("       %s", "MASKPROC");
               break;
           default:
               printf("       %s", " ");
               break;
       }


       printf("              0x%-4X\n", (phdr)->p_align);
    }
#if MA
    
    if(phdrs != NULL){
       phdrs = phdrs - PHDR_SIZE;
       free(phdrs);
    }
       
#endif
#endif
   close(fd);


   return (EXIT_SUCCESS);
}

运行程序截图:

ELF(三)程序头表_第2张图片

你可能感兴趣的:(unix,Elf,phdr,Elf,c)