【问题标题】:ELF program segments offset in fileELF 程序段在文件中的偏移量
【发布时间】:2021-07-08 16:34:35
【问题描述】:

我有一个问题,关于文件中的精灵程序段大小。比如一个程序readelf -f xx -W是这样的:

Program Headers:

  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  PHDR           0x000040 0x0000000000400040 0x0000000000400040 0x0001f8 0x0001f8 R E 0x8
  INTERP         0x000238 0x0000000000400238 0x0000000000400238 0x00001c 0x00001c R   0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x000000 0x0000000000400000 0x0000000000400000 0x4ca8e6 0x4ca8e6 R E 0x200000
  LOAD           0x4cb000 0x0000000000acb000 0x0000000000acb000 0x035db8 0x04ed80 RW  0x200000
  DYNAMIC        0x4ed4c8 0x0000000000aed4c8 0x0000000000aed4c8 0x000230 0x000230 RW  0x8
  NOTE           0x000254 0x0000000000400254 0x0000000000400254 0x000044 0x000044 R   0x4
  TLS            0x4cb000 0x0000000000acb000 0x0000000000acb000 0x000010 0x000018 R   0x10
  GNU_EH_FRAME   0x3dcf04 0x00000000007dcf04 0x00000000007dcf04 0x024c64 0x024c64 R   0x4
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10

 Section to Segment mapping:
  Segment Sections...

   00     
   01     .interp 
   02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame .gcc_except_table 
   03     .tdata .init_array .fini_array .jcr .data.rel.ro .dynamic .got .got.plt .data .bss 
   04     .dynamic 
   05     .note.ABI-tag .note.gnu.build-id 
   06     .tdata .tbss 
   07     .eh_frame_hdr 
   08     

第一个加载从偏移量0x000000 开始,大小为0x4ca8e6。为什么第二个偏移量不是(0x000000 + 0x4ca8e6),我看到(0x4cb000 - 0x4ca8e6)的内容,全为0。我无法理解。文件中的偏移量规则是什么?

【问题讨论】:

    标签: elf


    【解决方案1】:

    第一次加载从偏移量 0x000000 开始,大小为 0x4ca8e6。为什么第二个偏移量不是 (0x000000 + 0x4ca8e6)

    因为加载器mmaps LOAD 直接分段到内存中,所以对于每个LOAD 分段,以下必须为真:(p_vaddr - p_offset) % page_size == 0

    x86_64 上,最大页面大小为 2MiB (0x200000)。这对第二个(及后续)LOAD 段位置施加了严格限制。

    【讨论】:

    • 第一次加载p_vaddr为0x0000000000400000,memsize为0x4ca8e6,align为0x200000.so,align size为0xa00000。偏移量 0x000000 + 0x4ca8e6 = 0x4ca8e6.Last, ( 0xa00000 - 0x4ca8e6 ) % 0x200000 需要 0。现在需要附加零字节。但是为什么最后一个 p_vaddr 是 0x0000000000acb000 而最后一个偏移量是 0x4cb000 。
    猜你喜欢
    • 2014-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多