我正在尝试为该程序生成一个静态可执行文件(使用 musl):
电源:
.section .text
.global main
main:
mov $msg, %rdi
mov $0, %rax
call printf
mov %rax, %rdi
mov $60, %rax
syscall
msg:
.ascii "hello world from printf\n\0"
编译命令:
clang -g -c main.S -o main.o
链接命令(musl libc 放在musl
目录下(1.2.1 版)):
ld main.o musl/crt1.o -o sm -Tstatic.ld -static -lc -lm -Lmusl
链接描述文件 ( static.ld
):
ENTRY(_start)
SECTIONS
{
. = 0x100e8;
}
此配置会生成一个工作可执行文件,但如果我将位置计数器偏移量更改为0x10000
or 0x20000
,则生成的可执行文件在启动期间会因段错误而崩溃。在调试时,我发现 musl 初始化代码试图读取程序头(在 aux 向量中接收到的位置),并且由于某种原因,由 aux 向量给出的程序头的内存地址未映射到我们的地址空间中。
这种行为的原因是什么?链接描述文件中的计数器偏移到底是什么?除了更改加载地址之外,它如何影响链接器输出?
注意:当 musl 初始化代码尝试访问程序头时会发生段错误