为什么精灵文件中的段可以重叠

时间:2012-06-03 15:46:55

标签: assembly elf segment

简单的C文件:

#include <stdio.h>
int main(){
    printf("Hello World");
    return 0;
}

编译代码后,使用readelf -a a.out,精灵信息如下:

elf program headers, segment info

问题:

  1. 几个部分出现在不同的部分,例如第2和第3部分的interp部分。一个部分如何出现在多个细分中?
  2. 第二段的地址来自0x8048134,但是第三个LOAD段从0x8048000开始,带有0x004d0 memsize。那两段重叠?两个段如何在内存中重叠?
  3. 为什么程序头的偏移量和viraddr必须是以页面大小为模的同心?

2 个答案:

答案 0 :(得分:3)

您可能在部分表中有垃圾,或者可能完全丢失。对动态加载程序而言最重要的是段表(程序头),即使这样,只有PT_LOAD段不应该重叠*。其他类型的段(INTERP,DYNAMIC等)为加载器提供了额外的信息,通常是指LOAD段的某些部分。

*以下是the spec所说的内容:

PT_LOAD数组元素指定可加载的细分,由p_fileszp_memsz描述。文件中的字节映射到内存段的开头。如果段的内存大小(p_memsz)大于文件大小(p_filesz),则定义“额外”字节以保存值0并跟随段的初始化区域。文件大小可能不会大于内存大小。程序头表中的可加载段条目按升序显示,按p_vaddr成员排序。

正如你所看到的,没有提到重叠,所以它似乎并不被禁止,尽管我认为我没有看到任何PT_LOAD段重叠的文件。

答案 1 :(得分:0)

  
      
  1. 几个部分出现在不同的部分,例如第2和第3部分的interp部分。
  2.   

因此?

  

一个部分如何出现在多个细分中?

为什么不呢?

一个部分不会出现在多个PT_LOAD细分中,但.interpPT_LOAD中出现的PT_INTERP没有任何问题。

  
      
  1. 两段如何在内存中重叠?
  2.   

再次,为什么不呢?

  
      
  1. 为什么程序头的偏移量和viraddr必须是以页面大小为模的同心?
  2.   

因为否则mmap段无法显示在virtaddr上。