assembly – ELF程序头偏移量

我像这样手动编写一个可执行的ELF头程序头:

elf_head:
e_ident db      7Fh, 'ELF', 1, 1, 1
        times   9 db 0
e_type  dw      2                       ; ET_EXEC
e_mach  dw      3                       ; EM_386
e_ver   dd      1                       ; EV_CURRENT
e_entry dd      0x08048000+elf_head_len ; entry point
e_phoff dd      34h                     ; program header table offset
e_shoff dd      00h                     ; section header table offset
e_flags dd      0                       ; flags
e_elfhs dw      34h                     ; ELF header size
e_phes  dw      20h                     ; program header entry size
e_phec  dw      01h                     ; program header entries count
e_shes  dw      00h                     
e_shec  dw      00h                    
e_shsn  dw      00h                     
elf_ph:
p_type  dd      01h                     ; PT_LOAD
p_off   dd      elf_head_len        
p_vaddr dd      0x08048000+elf_head_len 
p_paddr dd      0x08048000+elf_head_len 
p_filsz dd      elf_head_len+file_len           
p_memsz dd      elf_head_len+file_len      
p_flags dd      7                       ; segment flags (RWX)
p_align dd      0x1000                  ; page_size==4096bytes
elf_head_len  equ  $- elf_head

我在p_align字段后面设置了e_entry字段点,我将代码放入正在创建的文件中.但它不起作用!我对p_offset字段有点困惑.我从文件的开头(0x00)开始有一个偏移,直到段代码的第一个字节.由于段的代码在p_align字段之后开始,我是否正确输入值elf_head_len?当我尝试运行新创建的可执行文件时,bash响应:分段错误!

好吧,我发现我在程序上出现错误,导致分段错误. (对于那个很抱歉).但问题仍然是关于p_off字段,我还想出,如果我设置p_off dd 0和p_vaddr dd 0x08048000和p_paddr dd 0x08048000可执行文件工作.如果我输入p_off dd elf_head_len和p_vaddr dd 0x08048000 elf_head_len和p_paddr dd 0x08048000 elf_head_len,它也可以工作.这让我想起了我读到的关于p_off和p_vaddr值的ELF格式的一些必须一致的东西(我认为它们必须在每个页面大小模数时给出相同的结果).所以这就是程序使用这些值的原因.所以现在的问题是:如果上述逻辑出现错误,请考虑纠正.

最佳答案 ELF规范要求对于需求分页的可执行文件,段的文件偏移量和虚拟地址必须确实匹配低阶位.

这些限制与mmap()系统调用放置在映射上的限制相同 – 它只接受文件中偏移量的映射,该偏移量是页面大小的倍数.映射ELF文件时,段会扩展到最近的页边界,因此除了段大小计算外,有效地忽略低位.

一个可能的理由是底层设备可能已经是内存映射 – 例如帧缓冲区或闪存 – 在这种情况下,它会产生大量开销来创建具有非页面对齐的偏移的映射.

点赞