USE*_*372 6 c gnu elf linker-scripts
我正在从文本“Operating Systems from 0 to 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) }
}
Run Code Online (Sandbox Code Playgroud)
用于链接ac文件;主程序
void test() {}
int main(int argc, char *argv[])
{
asm("mov %eax, 0x1\n"
"mov %ebx, 0x0\n"
"int $0x80");
}
Run Code Online (Sandbox Code Playgroud)
然后将main.c编译为目标文件;
gcc -m32 -g -c main.c
Run Code Online (Sandbox Code Playgroud)
但是,当使用链接描述文件时;
ld -m elf_i386 -o main -T main.lds main.o
ld: main: error: PHDR segment not covered by LOAD segment
Run Code Online (Sandbox Code Playgroud)
尽管当我更改 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
Run Code Online (Sandbox Code Playgroud)
PT_PHDR 段和 PT_LOAD 段从相同的 VA 开始。
有没有办法编写链接器脚本以便将段分开?还有为什么会出现这个错误呢?
程序头在运行时需要,因此必须加载它们,因此需要用段覆盖PT_LOAD。
大多数段类型至少与一个LOAD段重叠,因为它们描述了加载数据的位置。我能想到的唯一例外是该PT_GNU_STACK段。