在MIPS上加载ELF,malloc问题
我正在用MIPS(32位)加载一个普通的静态链接ELF二进制文件。映射可加载段后,在跳入目标ELF的CRT在MIPS上加载ELF,malloc问题,mips,elf,libc,musl,Mips,Elf,Libc,Musl,我正在用MIPS(32位)加载一个普通的静态链接ELF二进制文件。映射可加载段后,在跳入目标ELF的CRT\u start功能之前,我就是这样设置堆栈的: __asm__(" \ addi $2, %[envN], 0 ;\ .env_loop:
\u start
功能之前,我就是这样设置堆栈的:
__asm__(" \
addi $2, %[envN], 0 ;\
.env_loop: \
addi $2, $2, -4 ;\
lw $3, 0($2) ;\
addi $sp, $sp, -4 ;\
sw $3, 0($sp) ;\
bne $2, %[env0], .env_loop ;\
addi $2, %[argN], 0 ;\
.arg_loop: \
addi $2, $2, -4 ;\
lw $3, 0($2) ;\
addi $sp, $sp, -4 ;\
sw $3, 0($sp) ;\
bne $2, %[arg0], .arg_loop ;\
addi $2, %[argc], 0 ;\
addi $sp, $sp, -4 ;\
sw $2, 0($sp) ;\
addi $2, %[func], 0 ;\
jr $2 ;"
:
: [envN] "r" (envp + envc + 1),
[env0] "r" (envp),
[argN] "r" (argv + argc + 1),
[arg0] "r" (argv),
[argc] "r" ((int32_t)argc),
[func] "r" (entry_point)
: "$2", "$3", "cc", "memory"
);
因此,我在堆栈上推送环境变量、命令行参数、argc
,最后跳到目标ELF的入口点。这可以正常工作,我最终在加载的程序的主函数中使用正确的命令行参数和所有东西,除了一件事:malloc
不工作!对它的任何调用都返回null,并将errno设置为ENOMEM
我正在使用的MIPS模拟器(qemu系统MIPS)有大量的空闲内存,如果我只是在不使用加载程序的情况下启动程序,它工作正常,因此它一定来自加载程序。但我不知道为什么;我对x86、x86_64和arm使用了相同的加载技术,它们都工作得很好,但由于某种原因,malloc在MIPS版本的加载程序中出现了故障
这里有什么我错过的吗?在跳转到加载的可执行文件之前,实际上需要做一些事情,这可能对MIPS很重要,但对我成功尝试过的其他体系结构却不重要?我想我应该在这里问一下是否有人曾经遇到过这个问题,因为我真的无法想象这里出了什么问题
我在Linux下运行它,并使用musl作为libc。经过一些调试后,我发现musl的expand_heap
函数中出现了差异,但我还没有从源代码到程序集的信息,因此不清楚错误是什么(musl对其他架构使用相同的malloc代码,它们工作得很好)
二进制文件是静态链接的(包括libc;它没有动态依赖关系),其他所有文件(printf、fopen等)在加载的二进制文件中都可以正常工作,但malloc显然是唯一的例外(当然还有realloc/calloc,我想是free)。所以这真的很令人费解。我不说MIPS汇编,但它看起来不像是在设置从MIPS ABI第3-30页开始定义的“辅助向量”,位于此处:-这可能是问题的原因?我已经有一段时间没有尝试MIPS了,但我认为您的辅助向量需要如下所示:
// main()'s pseudo arguments.
#define AT_PAGESZ 6
argv:
.word name
.word 0 // End of argv.
.word 0 // End of envp.
// Auxv
.word AT_PAGESZ
.word 4096 // Page size.
.word 0
我记得,页面大小auxv条目对于musl的MIPS是唯一的。您是否静态链接了
libc
?@user35443是的,二进制文件是静态链接的,并且具有libc静态链接(加载器也有自己的libc副本,因为它需要做一些mprotect/mmap工作,但两个副本在不同的地址空间中)我在堆栈上添加了“辅助向量”,但不幸的是,它似乎没有什么区别:(效果非常好!这正是我问这个问题时希望得到的答案和专业知识,非常感谢。你救了我一天。)@Thomas我一直致力于在纯金属环境中使用clang和musl。我现在正在研究ARM,但我希望很快回到Mips。这很酷;到目前为止,我们将musl与gcc结合使用,musl+clang似乎是理想的组合(gcc相当臃肿)但是我们还没有找到时间来设置它,没有太多文档(而musl-cross
附带了安装程序和预构建的gcc交叉编译器..)。如果您对预构建的clang二进制文件感兴趣,也可以将其作为多个目标的库,我会在Cheers上找到它们;我想,本周晚些时候我会看看ellcc.org