您的位置:首页 > 文旅 > 旅游 > 企业网络组网_用html和css制作个人网页_亚马逊跨境电商个人开店_互联网广告代理商

企业网络组网_用html和css制作个人网页_亚马逊跨境电商个人开店_互联网广告代理商

2025/2/25 22:01:55 来源:https://blog.csdn.net/justdoyaya/article/details/145766162  浏览:    关键词:企业网络组网_用html和css制作个人网页_亚马逊跨境电商个人开店_互联网广告代理商
企业网络组网_用html和css制作个人网页_亚马逊跨境电商个人开店_互联网广告代理商

本文介绍一个使用Rust实现的ELF加载器。

下面是elf_loader的仓库链接:

github:

https://github.com/weizhiao/elf_loaderhttps://github.com/weizhiao/elf_loader

crates.io:

https://crates.io/crates/elf_loaderhttps://crates.io/crates/elf_loader

1 它能做什么?

elf_loader能够从内存、文件加载各种形式的elf文件,包括Executable file、Shared object file和Position-Independent Executable file。

PS:后面这两个其实是一类格式,Position-Independent Executable file其实就是带有入口的Shared object file,即可以执行的Shared object file。

鉴于此,它能够被使用在以下地方:

1 在操作系统内核中使用它作为elf文件的加载器

2 使用它实现Rust版本的动态链接器。PS:我自己也实现了一个https://github.com/weizhiao/dlopen-rs

3 在嵌入式设备上使用它加载elf动态库

2 优势

✨ 可以在 no_std环境中工作✨

elf_loader不依赖Rust std,也不强制依赖libc和操作系统,因此可以在内核和嵌入式设备等no_std环境中使用。

✨速度快✨

elf_loader吸取了musl和glibc里ld.so实现的优点,并充分利用了Rust的一些特性(比如静态分发),可以生成性能出色的代码。基于elf_loader实现的动态链接器dlopen-rs性能比libloading(ld.so)更好。

✨非常容易移植,具有良好的可扩展性✨

如果你想要移植elf_loader,你只需为你的平台实现 Mmap和ElfObject trait。在实现Mmap trait时可以参考elf_loader提供的默认实现:

elf_loader/src/mmap at main · weizhiao/elf_loader

此外你可以使用elf_loader提供的hook函数来拓展elf_loader的功能,实现其他任何你想要的功能,在使用hook函数时可以参考dlopen-rs里的实现:https://github.com/weizhiao/dlopen-rs/blob/main/src/loader/mod.rs

✨提供异步接口✨

elf_loader提供了加载elf文件的异步接口,这使得它在某些并发加载elf文件的场景下有更高的性能上限。不过你需要根据自己的应用场景实现 Mmap和ElfObjectAsync trait。比如不使用mmap来直接映射elf文件,转而使用mmap+文件读取的方式(mmap创建内存空间再通过文件读取将elf文件的内容读取到mmap创建的空间中)来加载elf文件,这样就能充分利用异步接口带来的优势。

✨编译期检查✨

elf_loader利用Rust的生命周期机制,在编译期检查elf文件的依赖库是否被提前销毁,大大提高了安全性。 比如说有三个被elf_loader加载的动态库a,b,c,其中c依赖b,b依赖a,如果a,b中的任意一个在c drop之前被drop了,那么将不会程序通过编译。你可以在examples/relocate中验证这一点:elf_loader/examples/relocate.rs at main · weizhiao/elf_loader · GitHub

3 示例

加载一个简单的动态库:

use elf_loader::{Loader, mmap::MmapImpl, object::ElfFile};
use elf_loader::{Loader, mmap::MmapImpl, object::ElfFile};
use std::{collections::HashMap, ptr::null};fn main() {fn print(s: &str) {println!("{}", s);}// liba.so依赖的符号let mut map = HashMap::new();map.insert("__gmon_start__", null());map.insert("__cxa_finalize", null());map.insert("_ITM_registerTMCloneTable", null());map.insert("_ITM_deregisterTMCloneTable", null());map.insert("print", print as _);let pre_find = |name: &str| -> Option<*const ()> { map.get(name).copied() };// 加载动态库liba.solet mut loader = Loader::<MmapImpl>::new();let liba = loader.easy_load_dylib(ElfFile::from_path("target/liba.so").unwrap()).unwrap();// 重定位liba.so中的符号let a = liba.easy_relocate([].iter(), &pre_find).unwrap();// 调用liba.so中的函数alet f = unsafe { a.get::<fn() -> i32>("a").unwrap() };f();
}

4 补充

如果你在使用时遇到任何问题,都可以在本文的评论区或者github上提出问题,此外十分欢迎任何对elf加载器感兴趣的朋友贡献代码(改进elf_loader本身,增加样例,修改文档中存在的问题都可以)。如果觉得elf_loader对你有帮助的话不妨点个star。^v^

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com