背景
由 @Chiichen 开发了动态链接相关的支持,但是有些bug,需要 @sig-mm 的同学帮忙调一下。
这个帖子用于跟踪该问题及其解决进展。
代码:GitHub - DragonOS-Community/DragonOS at feat-dynamic-link
由 @Chiichen 开发了动态链接相关的支持,但是有些bug,需要 @sig-mm 的同学帮忙调一下。
这个帖子用于跟踪该问题及其解决进展。
代码:GitHub - DragonOS-Community/DragonOS at feat-dynamic-link
@Chiichen 是那个glibc-hello-world的问题吗?
对,我等会把相关报错贴在下面
有一处要修改为 let result = BinaryLoaderResult::new(interp_load_addr.unwrap_or(program_entrypoint));
,但是修改后地址变成0x1
了
感觉这个报错是没有正确的拼接动态链接库的路径?
我是拉取feat-dynamic-link分支最新代码,然后直接运行的,还需要做什么操作吗?
你先检查一下/lib64/ld-linux-x86-64.so.2这个文件有没有,我记得好像是只在/lib下有,你可能要手动给他复制一份。
确实是这个问题,我拷贝后就复现bug了
@Chiichen 我看了下,直接的原因是地址0x0不仅没有映射到对应物理地址,也没有分配vma,导致在do_page_fault里调用find_nearest的时候获取到的vma有点问题。因为这个函数是找到离地址最近的一个vma,所以不一定会包含该地址
更加详细的原因可能我还需要看下其它内存区域的vma分配,因为用户程序申请堆内存时一般都是会分配一个vma的
我在 @Chiichen 的分支基础上修了几个bug,并且合并了还未合并到主线的文件映射pr(因为加载动态链接库需要文件映射):
现在已经能成功运行测试程序了
目前有个问题,rust动态编译出来的文件都会依赖一个libgcc_s.so.1的动态库
由于glibc不包含该库,所以要运行rust编译的程序需要编译gcc获取libgcc或者从本地拷贝,而且gcc编译很慢,想问下有什么解决方法
我的开发分支:
Well done你可以先开一个PR到那个开发分支上,就把现在能运行测试程序的版本提交上去。
我觉得暂时直接打包gcc的动态库就好了,应该只是需要这一个动态库就够了这里应该可以下载到不同版本的工具链,你看看有没有这个动态库。
@MemoryShore 所以之前是啥问题哈哈哈,可以在这简单分享一下~?
load_elf_interp函数加载解释器地址错误
程序入口错误
ElfLoader::load()方法里,应该返回解释器入口作为程序入口,将主程序入口写入auxv给解释器读取,原来刚好写反了
movaps指令导致#GP异常
解释器运行时经常出现#GP异常,通过objdump反编译解释器,然后在内核中打印解释器加载的偏移量+panic时的rip地址进行定位,确定执行到movaps指令时出错。
查看英特尔开发手册对于movaps的描述:
SYS_EXIT_GROUP
通过反汇编发现,访问_dl_random变量时会访问0x0地址导致page_fault,查资料后发现_dl_random是内核提供的随机数生成的种子数的地址,这个地址存放在auxv的AT_RANDOM中,而当时内核是没有实现的,所以_dl_random默认被设为地址0导致page_fault
给auxv添加AT_RANDOM即可解决(DragonOS里是AtType::Random)
16字节对齐那个,你现在这写法不对。你这是压的1个字节,能跑应该是巧合而已。
我认为正确解法是:
如何对齐?
对齐的时候调用ustack.sp()
就能获取当前压完之后的栈指针,通过与0xf
进行按位与的运算,就能知道要补全多少字节了,然后压对应的字节数进去。
因为在对齐之前有一个压随机数的操作
至于对齐的位置,我尝试过在压入argc之后对齐,结果发现会导致访问地址异常,我再调试一下看看问题出在哪
啊这,我感觉直接压八个byte好过了。
我想想,哦,是我记错了。argc之后是不能再去压的。
参考linux内核create_elf_tables
函数
binfmt_elf.c - OpenGrok cross reference for /linux-6.6.21/fs/binfmt_elf.c (dragonos.org.cn)
我发现linux是在最后,先将auxv创建好,然后直接让sp移动auxv+envp+argv+argc的长度
然后从下往上依次写入数据
也就是说应该在写入auxv之前插入空值,让后面对齐,并且auxv、envp、argv和argc应该连在一起
我的想法刚好对上了linux的做法,笑死