错误:LOAD段未覆盖PHDR段

问题描述

我正在学习从文本“从0到1的操作系统”链接脚本,在文本中他们展示了一个使用关键字PHDRS的示例;

ENTRY(main);
    
PHDRS
{
    headers PT_PHDR FILEHDR PHDRS;
    code PT_LOAD FILEHDR;
}
    
SECTIONS /*top level command that declares a list of custom program sections,ld provides set of such instructions.*/
{
    . = 0x10000; /* set location counter to address 0x10000,base address for subsequent commands */
    .text : { *(.text) } :code /* final .text section begins at address 0x1000,combines all .text sections from obj files into one final*/
    . = 0x8000000; 
    .data : { *(.data) } /*wildcard means all obj file .data sections*/
    .bss : { *(.bss) }
}

用于链接c文件; main.c

void test() {}

int main(int argc,char *argv[])
{
    asm("mov %eax,0x1\n"
         "mov %ebx,0x0\n"
         "int $0x80");
}

然后将main.c编译为目标文件;

gcc -m32 -g -c main.c

但是,使用链接程序脚本时;

ld -m elf_i386 -o main -T main.lds main.o
ld: main: error: PHDR segment not covered by LOAD segment

产生错误,尽管当我更改PT_LOAD段以包含PHDRS关键字时, 那么链接器将正常工作。

然后在使用readelf检查之后;

readelf -l main

Elf file type is EXEC (Executable file)
Entry point 0x10010
There are 2 program headers,starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000000 0x0000f000 0x0000f000 0x00074 0x00074 R   0x4
  LOAD           0x000000 0x0000f000 0x0000f000 0x7ff100c 0x7ff100c RWE 0x1000

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .text .text.__x86.get_pc_thunk.ax .eh_frame .got.plt 

PT_PHDR段和PT_LOAD段从相同的VA开始。

有没有一种方法可以编写链接描述文件,以使各段分开? 还有为什么会发生此错误?

解决方法

在运行时需要程序标头,因此必须加载它们,因此需要用PT_LOAD段覆盖。

大多数段类型与至少一个LOAD段重叠,因为它们描述了加载数据的位置。我唯一想到的例外是PT_GNU_STACK段。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...