为什么 ELF 的 vaddr 没有页面对齐?

Why ELF's vaddr is not page aligned?

我正在尝试构建一个类似 xv6 的系统,我正在复制以下 xv6 的代码:

    if (ph.p_vaddr % PGSIZE) {
            cprintf("exec: addr not page aligned.\n");
            goto bad;
    }

这是ELF加载到内存的部分。

它检查每个 PT_LOAD 段的 vaddr 并确保它在加载到内存之前是页面对齐的。

但是代码很混乱,因为当我使用 readelf 检查要加载的 ELF 文件时:

Elf file type is EXEC (Executable file)
Entry point 0x400260
There are 4 program headers, starting at offset 64

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  LOAD           0x000000 0x0000000000400000 0x0000000000400000 0x0021f0 0x0021f0 R E 0x1000
  LOAD           0x002eb8 0x0000000000403eb8 0x0000000000403eb8 0x000268 0x0008e8 RW  0x1000
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10
  GNU_RELRO      0x002eb8 0x0000000000403eb8 0x0000000000403eb8 0x000148 0x000148 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     .init .text .fini .rodata .eh_frame 
   01     .init_array .fini_array .data.rel.ro .got .got.plt .data .bss 
   02     
   03     .init_array .fini_array .data.rel.ro .got .got.plt 

vaddr并不总是页对齐的,请问是我的编译方式有问题还是代码本身有问题?

is it something wrong with my way of compiling or the code itself is wrong?

代码有误。 .p_vaddr - .p_offset 必须是 page-aligned; .p_vaddr 单独不必。

这是因为段需要mmap编辑,而mmap需要page-aligned偏移量。为了 mmap 第二段 .p_vaddr,加载程序向下舍入 .p_vaddr.p_offset,以及 mmap在段的开头有点多余。